OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [docs/] [datasheet/] [software.adoc] - Blame information for rev 70

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 60 zero_gravi
:sectnums:
2
== Software Framework
3
 
4
To make actual use of the NEORV32 processor, the project comes with a complete software eco-system. This
5
ecosystem is based on the RISC-V port of the GCC GNU Compiler Collection and consists of the following elementary parts:
6
 
7
[cols="<6,<4"]
8
[grid="none"]
9
|=======================
10
| Application/bootloader start-up code | `sw/common/crt0.S`
11
| Application/bootloader linker script | `sw/common/neorv32.ld`
12
| Core hardware driver libraries | `sw/lib/include/` & `sw/lib/source/`
13 62 zero_gravi
| Central makefile | `sw/common/common.mk`
14 60 zero_gravi
| Auxiliary tool for generating NEORV32 executables | `sw/image_gen/`
15
| Default bootloader | `sw/bootloader/bootloader.c`
16
|=======================
17
 
18
Last but not least, the NEORV32 ecosystem provides some example programs for testing the hardware, for
19
illustrating the usage of peripherals and for general getting in touch with the project (`sw/example`).
20
 
21
// ####################################################################################################################
22
:sectnums:
23
=== Compiler Toolchain
24
 
25
The toolchain for this project is based on the free RISC-V GCC-port. You can find the compiler sources and
26
build instructions on the official RISC-V GNU toolchain GitHub page: https://github.com/riscv/riscv-gnutoolchain.
27
 
28
The NEORV32 implements a 32-bit base integer architecture (`rv32i`) and a 32-bit integer and soft-float ABI
29
(ilp32), so make sure you build an according toolchain.
30
 
31
Alternatively, you can download my prebuilt `rv32i/e` toolchains for 64-bit x86 Linux from: https://github.com/stnolting/riscv-gcc-prebuilt
32
 
33
The default toolchain prefix used by the project's makefiles is (can be changed in the makefiles): **`riscv32-unknown-elf`**
34
 
35
[TIP]
36
More information regarding the toolchain (building from scratch or downloading the prebuilt ones)
37 61 zero_gravi
can be found in the user guides' section https://stnolting.github.io/neorv32/ug/#_software_toolchain_setup[Software Toolchain Setup].
38 60 zero_gravi
 
39
 
40
 
41
<<<
42
// ####################################################################################################################
43
:sectnums:
44
=== Core Libraries
45
 
46
The NEORV32 project provides a set of C libraries that allows an easy usage of the processor/CPU features.
47
Just include the main NEORV32 library file in your application's source file(s):
48
 
49
[source,c]
50
----
51
#include 
52
----
53
 
54 69 zero_gravi
[TIP]
55
A CMSIS-SVD-compatible **System View Description (SVD)** file including all peripherals is available in `sw/svd`.
56
 
57 60 zero_gravi
Together with the makefile, this will automatically include all the processor's header files located in
58
`sw/lib/include` into your application. The actual source files of the core libraries are located in
59
`sw/lib/source` and are automatically included into the source list of your software project. The following
60
files are currently part of the NEORV32 core library:
61
 
62
[cols="<3,<4,<8"]
63
[options="header",grid="rows"]
64
|=======================
65
| C source file | C header file | Description
66
| -                  | `neorv32.h`            | main NEORV32 definitions and library file
67
| `neorv32_cfs.c`    | `neorv32_cfs.h`        | HW driver (stub)footnote:[This driver file only represents a stub, since the real CFS drivers are defined by the actual CFS implementation.] functions for the custom functions subsystem
68
| `neorv32_cpu.c`    | `neorv32_cpu.h`        | HW driver functions for the NEORV32 **CPU**
69
| `neorv32_gpio.c`   | `neorv32_gpio.h`       | HW driver functions for the **GPIO**
70 67 zero_gravi
| `neorv32_gptmr.c`  | `neorv32_gptmr.h`      | HW driver functions for the **GPTRM**
71 69 zero_gravi
| -                  | `neorv32_intrinsics.h` | macros for (custom) intrinsics/instructions
72 60 zero_gravi
| `neorv32_mtime.c`  | `neorv32_mtime.h`      | HW driver functions for the **MTIME**
73
| `neorv32_neoled.c` | `neorv32_neoled.h`     | HW driver functions for the **NEOLED**
74
| `neorv32_pwm.c`    | `neorv32_pwm.h`        | HW driver functions for the **PWM**
75
| `neorv32_rte.c`    | `neorv32_rte.h`        | NEORV32 **runtime environment** and helpers
76 67 zero_gravi
| `neorv32_slink.c`  | `neorv32_slink.h`      | HW driver functions for the **SLINK**
77 60 zero_gravi
| `neorv32_spi.c`    | `neorv32_spi.h`        | HW driver functions for the **SPI**
78
| `neorv32_trng.c`   | `neorv32_trng.h`       | HW driver functions for the **TRNG**
79
| `neorv32_twi.c`    | `neorv32_twi.h`        | HW driver functions for the **TWI**
80
| `neorv32_uart.c`   | `neorv32_uart.h`       | HW driver functions for the **UART0** and **UART1**
81
| `neorv32_wdt.c`    | `neorv32_wdt.h`        | HW driver functions for the **WDT**
82 70 zero_gravi
| `neorv32_xip.c`    | `neorv32_xip.h`        | HW driver functions for the **XIP**
83 67 zero_gravi
| `neorv32_xirq.c`   | `neorv32_xirq.h`       | HW driver functions for the **XIRQ**
84 60 zero_gravi
|=======================
85
 
86
.Documentation
87
[TIP]
88
All core library software sources are highly documented using _doxygen_. See section <>.
89
The documentation is automatically built and deployed to GitHub pages by the CI workflow (:https://stnolting.github.io/neorv32/sw/files.html).
90
 
91
 
92
 
93
 
94
<<<
95
// ####################################################################################################################
96
:sectnums:
97
=== Application Makefile
98
 
99 62 zero_gravi
Application compilation is based on a single, centralized **GNU makefiles** `sw/common/common.mk`. Each project in the
100
`sw/example` folder features a makefile that just includes this central makefile. When creating a new project, copy an existing project folder or
101 60 zero_gravi
at least the makefile to your new project folder. I suggest to create new projects also in `sw/example` to keep
102
the file dependencies. Of course, these dependencies can be manually configured via makefiles variables
103
when your project is located somewhere else.
104
 
105 62 zero_gravi
[NOTE]
106 60 zero_gravi
Before you can use the makefiles, you need to install the RISC-V GCC toolchain. Also, you have to add the
107 62 zero_gravi
installation folder of the compiler to your system's `PATH` variable. More information can be found in
108
https://stnolting.github.io/neorv32/ug/#_software_toolchain_setup[User Guide: Software Toolchain Setup].
109 60 zero_gravi
 
110
The makefile is invoked by simply executing make in your console:
111
 
112
[source,bash]
113
----
114
neorv32/sw/example/blink_led$ make
115
----
116
 
117
:sectnums:
118
==== Targets
119
 
120 62 zero_gravi
Just executing `make` (or executing `make help`) will show the help menu listing all available targets.
121 60 zero_gravi
 
122 62 zero_gravi
[source,makefile]
123
----
124
$ make
125 69 zero_gravi
<<< NEORV32 SW Application Makefile >>>
126 62 zero_gravi
Make sure to add the bin folder of RISC-V GCC to your PATH variable.
127 69 zero_gravi
 
128
== Targets ==
129
 help         - show this text
130
 check        - check toolchain
131
 info         - show makefile/toolchain configuration
132
 exe          - compile and generate  executable for upload via bootloader
133
 hex          - compile and generate  executable raw file
134
 image        - compile and generate VHDL IMEM boot image (for application) in local folder
135
 install      - compile, generate and install VHDL IMEM boot image (for application)
136
 sim          - in-console simulation using default/simple testbench and GHDL
137
 all          - exe + hex + install
138
 elf_info     - show ELF layout info
139
 clean        - clean up project
140
 clean_all    - clean up project, core libraries and image generator
141
 bl_image     - compile and generate VHDL BOOTROM boot image (for bootloader only!) in local folder
142
 bootloader   - compile, generate and install VHDL BOOTROM boot image (for bootloader only!)
143
 
144
== Variables ==
145
 USER_FLAGS   - Custom toolchain flags [append only], default ""
146
 EFFORT       - Optimization level, default "-Os"
147
 MARCH        - Machine architecture, default "rv32i"
148
 MABI         - Machine binary interface, default "ilp32"
149
 APP_INC      - C include folder(s) [append only], default "-I ."
150
 ASM_INC      - ASM include folder(s) [append only], default "-I ."
151
 RISCV_PREFIX - Toolchain prefix, default "riscv32-unknown-elf-"
152
 NEORV32_HOME - NEORV32 home folder, default "../../.."
153 62 zero_gravi
----
154 60 zero_gravi
 
155
 
156
:sectnums:
157
==== Configuration
158
 
159 62 zero_gravi
The compilation flow is configured via variables right at the beginning of the **central**
160
makefile (`sw/common/common.mk`):
161 60 zero_gravi
 
162 62 zero_gravi
[TIP]
163
The makefile configuration variables can be (re-)defined directly when invoking the makefile. For
164 65 zero_gravi
example via `$ make MARCH=rv32ic clean_all exe`. You can also make project-specific definitions
165 62 zero_gravi
of all variables inside the project's actual makefile (e.g., `sw/example/blink_led/makefile`).
166
 
167 60 zero_gravi
[source,makefile]
168
----
169
# *****************************************************************************
170
# USER CONFIGURATION
171
# *****************************************************************************
172
# User's application sources (*.c, *.cpp, *.s, *.S); add additional files here
173
APP_SRC ?= $(wildcard ./*.c) $(wildcard ./*.s) $(wildcard ./*.cpp) $(wildcard ./*.S)
174
# User's application include folders (don't forget the '-I' before each entry)
175
APP_INC ?= -I .
176
# User's application include folders - for assembly files only (don't forget the '-I' before each
177
entry)
178
ASM_INC ?= -I .
179
# Optimization
180
EFFORT ?= -Os
181
# Compiler toolchain
182 62 zero_gravi
RISCV_PREFIX ?= riscv32-unknown-elf-
183 60 zero_gravi
# CPU architecture and ABI
184 65 zero_gravi
MARCH ?= rv32i
185
MABI  ?= ilp32
186 60 zero_gravi
# User flags for additional configuration (will be added to compiler flags)
187
USER_FLAGS ?=
188
# Relative or absolute path to the NEORV32 home folder
189
NEORV32_HOME ?= ../../..
190
# *****************************************************************************
191
----
192
 
193
[cols="<3,<10"]
194
[grid="none"]
195
|=======================
196
| _APP_SRC_         | The source files of the application (`*.c`, `*.cpp`, `*.S` and `*.s` files are allowed; file of these types in the project folder are automatically added via wildcards). Additional files can be added; separated by white spaces
197
| _APP_INC_         | Include file folders; separated by white spaces; must be defined with `-I` prefix
198
| _ASM_INC_         | Include file folders that are used only for the assembly source files (`*.S`/`*.s`).
199
| _EFFORT_          | Optimization level, optimize for size (`-Os`) is default; legal values: `-O0`, `-O1`, `-O2`, `-O3`, `-Os`
200 62 zero_gravi
| _RISCV_PREFIX_    | The toolchain prefix to be used; follows the naming convention "architecture-vendor-output-"
201 65 zero_gravi
| _MARCH_           | The targeted RISC-V architecture/ISA. Only `rv32` is supported by the NEORV32. Enable compiler support of optional CPU extension by adding the according extension letter (e.g. `rv32im` for _M_ CPU extension). See https://stnolting.github.io/neorv32/ug/#_enabling_risc_v_cpu_extensions[User Guide: Enabling RISC-V CPU Extensions] for more information.
202 60 zero_gravi
| _MABI_            | The default 32-bit integer ABI.
203
| _USER_FLAGS_      | Additional flags that will be forwarded to the compiler tools
204
| _NEORV32_HOME_    | Relative or absolute path to the NEORV32 project home folder. Adapt this if the makefile/project is not in the project's `sw/example folder`.
205
|=======================
206
 
207
:sectnums:
208
==== Default Compiler Flags
209
 
210
The following default compiler flags are used for compiling an application. These flags are defined via the
211
`CC_OPTS` variable. Custom flags can be appended via the `USER_FLAGS` variable to the `CC_OPTS` variable.
212
 
213
[cols="<3,<9"]
214
[grid="none"]
215
|=======================
216
| `-Wall` | Enable all compiler warnings.
217
| `-ffunction-sections` | Put functions and data segment in independent sections. This allows a code optimization as dead code and unused data can be easily removed.
218
| `-nostartfiles` | Do not use the default start code. The makefiles use the NEORV32-specific start-up code instead (`sw/common/crt0.S`).
219
| `-Wl,--gc-sections` | Make the linker perform dead code elimination.
220
| `-lm` | Include/link with `math.h`.
221
| `-lc` | Search for the standard C library when linking.
222
| `-lgcc` | Make sure we have no unresolved references to internal GCC library subroutines.
223 66 zero_gravi
| `-mno-fdiv` | Use built-in software functions for floating-point divisions and square roots (since the according instructions are not supported yet).
224 60 zero_gravi
| `-falign-functions=4` .4+| Force a 32-bit alignment of functions and labels (branch/jump/call targets). This increases performance as it simplifies instruction fetch when using the C extension. As a drawback this will also slightly increase the program code.
225
| `-falign-labels=4`
226
| `-falign-loops=4`
227
| `-falign-jumps=4`
228
|=======================
229
 
230
 
231
 
232
<<<
233
// ####################################################################################################################
234
:sectnums:
235
=== Executable Image Format
236
 
237 61 zero_gravi
In order to generate a file, which can be executed by the processor, all source files have to be compiler, linked
238
and packed into a final _executable_.
239 60 zero_gravi
 
240 61 zero_gravi
:sectnums:
241
==== Linker Script
242
 
243
When all the application sources have been compiled, they need to be _linked_ in order to generate a unified
244
program file. For this purpose the makefile uses the NEORV32-specific linker script `sw/common/neorv32.ld` for
245
linking all object files that were generated during compilation.
246
 
247
The linker script defines three memory _sections_: `rom`, `ram` and `iodev`. Each section provides specific
248
access _attributes_: read access (`r`), write access (`w`) and executable (`x`).
249
 
250
.Linker memory sections - general
251 60 zero_gravi
[cols="<2,^1,<7"]
252
[options="header",grid="rows"]
253
|=======================
254
| Memory section  | Attributes | Description
255 61 zero_gravi
| `ram`           | `rwx`      | Data memory address space (processor-internal/external DMEM)
256
| `rom`           | `rx`       | Instruction memory address space (processor-internal/external IMEM) _or_ internal bootloader ROM
257
| `iodev`         | `rw`       | Processor-internal memory-mapped IO/peripheral devices address space
258 60 zero_gravi
|=======================
259
 
260 61 zero_gravi
These sections are defined right at the beginning of the linker script:
261 60 zero_gravi
 
262 61 zero_gravi
.Linker memory sections - cut-out from linker script `neorv32.ld`
263
[source,c]
264
----
265
MEMORY
266
{
267
  ram  (rwx) : ORIGIN = 0x80000000, LENGTH = DEFINED(make_bootloader) ? 512 : 8*1024
268
  rom   (rx) : ORIGIN = DEFINED(make_bootloader) ? 0xFFFF0000 : 0x00000000, LENGTH = DEFINED(make_bootloader) ? 32K : 2048M
269
  iodev (rw) : ORIGIN = 0xFFFFFE00, LENGTH = 512
270
}
271
----
272 60 zero_gravi
 
273 61 zero_gravi
Each memory section provides a _base address_ `ORIGIN` and a _size_ `LENGTH`. The base address and size of the `iodev` section is
274
fixed and must not be altered. The base addresses and sizes of the `ram` and `rom` regions correspond to the total available instruction
275
and data memory address space (see section <<_address_space_layout>>).
276 60 zero_gravi
 
277 61 zero_gravi
[IMPORTANT]
278
`ORIGIN` of the `ram` section has to be always identical to the processor's `dspace_base_c` hardware configuration. Additionally,
279
`ORIGIN` of the `rom` section has to be always identical to the processor's `ispace_base_c` hardware configuration.
280
 
281
The sizes of `ram` section has to be equal to the size of the **physical available data instruction memory**. For example, if the processor
282
setup only uses processor-internal DMEM (<<_mem_int_dmem_en>> = _true_ and no external data memory attached) the `LENGTH` parameter of
283
this memory section has to be equal to the size configured by the <<_mem_int_dmem_size>> generic.
284
 
285
The sizes of `rom` section is a little bit more complicated. The default linker script configuration assumes a _maximum_ of 2GB _logical_
286
memory space, which is also the default configuration of the processor's hardware instruction memory address space. This size _does not_ have
287
to reflect the _actual_ physical size of the instruction memory (internal IMEM and/or processor-external memory). It just provides a maximum
288
limit. When uploading new executable via the bootloader, the bootloader itself checks if sufficient _physical_ instruction memory is available.
289
If a new executable is embedded right into the internal-IMEM the synthesis tool will check, if the configured instruction memory size
290
is sufficient (e.g., via the <<_mem_int_imem_size>> generic).
291
 
292
[IMPORTANT]
293
The `rom` region uses a conditional assignment (via the `make_bootloader` symbol) for `ORIGIN` and `LENGTH` that is used to place
294
"normal executable" (i.e. for the IMEM) or "the bootloader image" to their according memories. +
295
 +
296
The `ram` region also uses a conditional assignment (via the `make_bootloader` symbol) for `LENGTH`. When compiling the bootloader
297
(`make_bootloader` symbol is set) the generated bootloader will only use the _first_ 512 bytes of the data address space. This is
298
a fall-back to ensure the bootloader can operate independently of the actual _physical_ data memory size.
299
 
300
The linker maps all the regions from the compiled object files into four final sections: `.text`, `.rodata`, `.data` and `.bss`.
301
These four regions contain everything required for the application to run:
302
 
303
.Linker memory regions
304 60 zero_gravi
[cols="<1,<9"]
305
[options="header",grid="rows"]
306
|=======================
307 62 zero_gravi
| Region    | Description
308 60 zero_gravi
| `.text`   | Executable instructions generated from the start-up code and all application sources.
309
| `.rodata` | Constants (like strings) from the application; also the initial data for initialized variables.
310
| `.data`   | This section is required for the address generation of fixed (= global) variables only.
311
| `.bss`    | This section is required for the address generation of dynamic memory constructs only.
312
|=======================
313
 
314
The `.text` and `.rodata` sections are mapped to processor's instruction memory space and the `.data` and
315 61 zero_gravi
`.bss` sections are mapped to the processor's data memory space. Finally, the `.text`, `.rodata` and `.data`
316
sections are extracted and concatenated into a single file `main.bin`.
317 60 zero_gravi
 
318
 
319 61 zero_gravi
:sectnums:
320
==== Executable Image Generator
321 60 zero_gravi
 
322 61 zero_gravi
The `main.bin` file is packed by the NEORV32 image generator (`sw/image_gen`) to generate the final executable file.
323
 
324
[NOTE]
325
The sources of the image generator are automatically compiled when invoking the makefile.
326
 
327
The image generator can generate three types of executables, selected by a flag when calling the generator:
328
 
329 60 zero_gravi
[cols="<1,<9"]
330
[grid="none"]
331
|=======================
332
| `-app_bin` | Generates an executable binary file `neorv32_exe.bin` (for UART uploading via the bootloader).
333 62 zero_gravi
| `-app_hex` | Generates a plain ASCII hex-char file `neorv32_exe.hex` that can be used to initialize custom (instruction-) memories (in synthesis/simulation).
334 60 zero_gravi
| `-app_img` | Generates an executable VHDL memory initialization image for the processor-internal IMEM. This option generates the `rtl/core/neorv32_application_image.vhd` file.
335
| `-bld_img` | Generates an executable VHDL memory initialization image for the processor-internal BOOT ROM. This option generates the `rtl/core/neorv32_bootloader_image.vhd` file.
336
|=======================
337
 
338 61 zero_gravi
All these options are managed by the makefile. The _normal application_ compilation flow will generate the `neorv32_exe.bin`
339
executable to be upload via UART to the NEORV32 bootloader.
340 60 zero_gravi
 
341 61 zero_gravi
The image generator add a small header to the `neorv32_exe.bin` executable, which consists of three 32-bit words located right at the
342
beginning of the file. The first word of the executable is the signature word and is always `0x4788cafe`. Based on this word the bootloader
343
can identify a valid image file. The next word represents the size in bytes of the actual program
344 60 zero_gravi
image in bytes. A simple "complement" checksum of the actual program image is given by the third word. This
345
provides a simple protection against data transmission or storage errors.
346
 
347
 
348 61 zero_gravi
:sectnums:
349
==== Start-Up Code (crt0)
350 60 zero_gravi
 
351 61 zero_gravi
The CPU and also the processor require a minimal start-up and initialization code to bring the CPU (and the SoC)
352
into a stable and initialized state and to initialize the C runtime environment before the actual application can be executed.
353
This start-up code is located in `sw/common/crt0.S` and is automatically linked _every_ application program
354
and placed right before the actual application code so it gets executed right after reset.
355 60 zero_gravi
 
356 61 zero_gravi
The `crt0.S` start-up performs the following operations:
357 60 zero_gravi
 
358 61 zero_gravi
[start=1]
359
. Initialize all integer registers `x1 - x31` (or jsut `x1 - x15` when using the `E` CPU extension) to a defined value.
360
. Initialize the global pointer `gp` and the stack pointer `sp` according to the `.data` segment layout provided by the linker script.
361
. Initialize all CPU core CSRs and also install a default "dummy" trap handler for _all_ traps. This handler catches all traps during the early boot phase.
362
. Clear IO area: Write zero to all memory-mapped registers within the IO region (`iodev` section). If certain devices have not been implemented, a bus access fault exception will occur. This exception is captured by the dummy trap handler.
363
. Clear the `.bss` section defined by the linker script.
364
. Copy read-only data from the `.text` section to the `.data` section to set initialized variables.
365
. Call the application's `main` function (with _no_ arguments: `argc` = `argv` = 0).
366
. If the `main` function returns `crt0` can call an "after-main handler" (see below)
367
. If there is no after-main handler or after returning from the after-main handler the processor goes to an endless sleep mode (using a simple loop or via the `wfi` instruction if available).
368 60 zero_gravi
 
369 61 zero_gravi
:sectnums:
370
===== After-Main Handler
371
 
372
If the application's `main()` function actually returns, an _after main handler_ can be executed. This handler can be a normal function
373
since the C runtime is still available when executed. If this handler uses any kind of peripheral/IO modules make sure these are
374
already initialized within the application or you have to initialize them _inside_ the handler.
375
 
376
.After-main handler - function prototype
377
[source,c]
378
----
379
int __neorv32_crt0_after_main(int32_t return_code);
380
----
381
 
382
The function has exactly one argument (`return_code`) that provides the _return value_ of the application's main function.
383
For instance, this variable contains _-1_ if the main function returned with `return -1;`. The return value of the
384
`__neorv32_crt0_after_main` function is irrelevant as there is no further "software instance" executed afterwards that can check this.
385
However, the on-chip debugger could still evaluate the return value of the after-main handler.
386
 
387 70 zero_gravi
A simple `printf` can be used to inform the user when the application's main function returns
388 61 zero_gravi
(this example assumes that UART0 has been already properly configured in the actual application):
389
 
390
.After-main handler - example
391
[source,c]
392
----
393
int __neorv32_crt0_after_main(int32_t return_code) {
394
 
395 65 zero_gravi
  neorv32_uart0_printf("Main returned with code: %i\n", return_code);
396 61 zero_gravi
  return 0;
397
}
398
----
399
 
400
 
401 60 zero_gravi
<<<
402
// ####################################################################################################################
403
:sectnums:
404
=== Bootloader
405
 
406 61 zero_gravi
[NOTE]
407
This section illustrated the **default** bootloader from the repository. The bootloader can be customized
408
to target application-specific scenarios. See User Guide section
409
https://stnolting.github.io/neorv32/ug/#_customizing_the_internal_bootloader[Customizing the Internal Bootloader]
410
for more information.
411 60 zero_gravi
 
412 61 zero_gravi
The default NEORV32 bootloader (source code `sw/bootloader/bootloader.c`) provides a build-in firmware that
413
allows to upload new application executables via UART at every time and to optionally store/boot them to/from
414
an external SPI flash. It features a simple "automatic boot" feature that will try to fetch an executable
415
from SPI flash if there is _no_ UART user interaction. This allows to build processor setup with
416
non-volatile application storage, which can be updated at any time.
417 60 zero_gravi
 
418 61 zero_gravi
The bootloader is only implemented if the <<_int_bootloader_en>> generic is _true_. This will
419
select the <<_indirect_boot>> boot configuration.
420 60 zero_gravi
 
421 61 zero_gravi
.Hardware requirements of the _default_ NEORV32 bootloader
422 60 zero_gravi
[IMPORTANT]
423 61 zero_gravi
**REQUIRED**: The bootloader requires the CSR access CPU extension (<<_cpu_extension_riscv_zicsr>> generic is _true_)
424
and at least 512 bytes of data memory (processor-internal DMEM or external DMEM). +
425
 +
426
_RECOMMENDED_: For user interaction via UART (like uploading executables) the primary UART (UART0) has to be
427
implemented (<<_io_uart0_en>> generic is _true_). Without UART the bootloader does not make much sense. However, auto-boot
428
via SPI is still supported but the bootloader should be customized (see User Guide) for this purpose. +
429
 +
430
_OPTIONAL_: The default bootloader uses bit 0 of the GPIO output port as "heart beat" and status LED if the
431
GPIO controller is implemented (<<_io_gpio_en>> generic is _true_). +
432
 +
433
_OPTIONAL_: The MTIME machine timer (<<_io_mtime_en>> generic is _true_) and the SPI controller
434
(<<_io_spi_en>> generic is _true_) are required in order to use the bootloader's auto-boot feature
435
(automatic boot from external SPI flash if there is no user interaction via UART).
436 60 zero_gravi
 
437
To interact with the bootloader, connect the primary UART (UART0) signals (`uart0_txd_o` and
438
`uart0_rxd_o`) of the processor's top entity via a serial port (-adapter) to your computer (hardware flow control is
439
not used so the according interface signals can be ignored.), configure your
440 62 zero_gravi
terminal program using the following settings and perform a reset of the processor.
441 60 zero_gravi
 
442
Terminal console settings (`19200-8-N-1`):
443
 
444
* 19200 Baud
445
* 8 data bits
446
* no parity bit
447
* 1 stop bit
448
* newline on `\r\n` (carriage return, newline)
449
* no transfer protocol / control flow protocol - just the raw byte stuff
450
 
451 70 zero_gravi
[IMPORTANT]
452
_Any_ terminal program that can connect to a serial port should work. However, make sure the program
453
can transfer data in _raw_ byte mode without any protocol overhead around it. Some terminal programs struggle with
454
transmitting files larger than 4kB (see https://github.com/stnolting/neorv32/pull/215). Try a different program
455
if uploading a binary does not work (terminal stall).
456
 
457 60 zero_gravi
The bootloader uses the LSB of the top entity's `gpio_o` output port as high-active status LED (all other
458
output pin are set to low level by the bootloader). After reset, this LED will start blinking at ~2Hz and the
459
following intro screen should show up in your terminal:
460
 
461
[source]
462
----
463
<< NEORV32 Bootloader >>
464
 
465
BLDV: Mar 23 2021
466
HWV:  0x01050208
467
CLK:  0x05F5E100
468
MISA: 0x40901105
469 64 zero_gravi
CPU:  0x00000023
470
SOC:  0x0EFF0037
471 60 zero_gravi
IMEM: 0x00004000 bytes @ 0x00000000
472
DMEM: 0x00002000 bytes @ 0x80000000
473
 
474
Autoboot in 8s. Press key to abort.
475
----
476
 
477
This start-up screen also gives some brief information about the bootloader and several system configuration parameters:
478
 
479
[cols="<2,<15"]
480
[grid="none"]
481
|=======================
482
| `BLDV` | Bootloader version (built date).
483
| `HWV`  | Processor hardware version (from the `mimpid` CSR) in BCD format (example: `0x01040606` = v1.4.6.6).
484
| `CLK`  | Processor clock speed in Hz (via the SYSINFO module, from the _CLOCK_FREQUENCY_ generic).
485
| `MISA` | CPU extensions (from the `misa` CSR).
486 64 zero_gravi
| `CPU`  | CPU sub-extensions (via the `CPU` register in the SYSINFO module)
487
| `SOC`  | Processor configuration (via the `SOC` register in the SYSINFO module / from the IO_* and MEM_* configuration generics).
488 60 zero_gravi
| `IMEM` | IMEM memory base address and size in byte (from the _MEM_INT_IMEM_SIZE_ generic).
489
| `DMEM` | DMEM memory base address and size in byte (from the _MEM_INT_DMEM_SIZE_ generic).
490
|=======================
491
 
492
Now you have 8 seconds to press any key. Otherwise, the bootloader starts the auto boot sequence. When
493
you press any key within the 8 seconds, the actual bootloader user console starts:
494
 
495
[source]
496
----
497
<< NEORV32 Bootloader >>
498
 
499
BLDV: Mar 23 2021
500
HWV:  0x01050208
501
CLK:  0x05F5E100
502
USER: 0x10000DE0
503
MISA: 0x40901105
504 64 zero_gravi
CPU:  0x00000023
505
SOC:  0x0EFF0037
506 60 zero_gravi
IMEM: 0x00004000 bytes @ 0x00000000
507
DMEM: 0x00002000 bytes @ 0x80000000
508
 
509
Autoboot in 8s. Press key to abort.
510
Aborted.
511
 
512
Available commands:
513
h: Help
514
r: Restart
515
u: Upload
516
s: Store to flash
517
l: Load from flash
518
e: Execute
519
CMD:>
520
----
521
 
522
The auto-boot countdown is stopped and now you can enter a command from the list to perform the
523
corresponding operation:
524
 
525
* `h`: Show the help text (again)
526
* `r`: Restart the bootloader and the auto-boot sequence
527
* `u`: Upload new program executable (`neorv32_exe.bin`) via UART into the instruction memory
528 69 zero_gravi
* `s`: Store executable to SPI flash at `spi_csn_o(0)` (little-endian byte order)
529
* `l`: Load executable from SPI flash at `spi_csn_o(0)` (little-endian byte order)
530 60 zero_gravi
* `e`: Start the application, which is currently stored in the instruction memory (IMEM)
531
 
532
A new executable can be uploaded via UART by executing the `u` command. After that, the executable can be directly
533
executed via the `e` command. To store the recently uploaded executable to an attached SPI flash press `s`. To
534
directly load an executable from the SPI flash press `l`. The bootloader and the auto-boot sequence can be
535
manually restarted via the `r` command.
536
 
537
[TIP]
538
The CPU is in machine level privilege mode after reset. When the bootloader boots an application,
539
this application is also started in machine level privilege mode.
540
 
541 61 zero_gravi
[TIP]
542
For detailed information on using an SPI flash for application storage see User Guide section
543
https://stnolting.github.io/neorv32/ug/#_programming_an_external_spi_flash_via_the_bootloader[Programming an External SPI Flash via the Bootloader].
544 60 zero_gravi
 
545
 
546
:sectnums:
547
==== Auto Boot Sequence
548 61 zero_gravi
When you reset the NEORV32 processor, the bootloader waits 8 seconds for a UART console input before it
549 60 zero_gravi
starts the automatic boot sequence. This sequence tries to fetch a valid boot image from the external SPI
550 61 zero_gravi
flash, connected to SPI chip select `spi_csn_o(0)`. If a valid boot image is found that can be successfully
551
transferred into the instruction memory, it is automatically started. If no SPI flash is detected or if there
552
is no valid boot image found, and error code will be shown.
553 60 zero_gravi
 
554
 
555
:sectnums:
556
==== Bootloader Error Codes
557
 
558
If something goes wrong during bootloader operation, an error code is shown. In this case the processor
559
stalls, a bell command and one of the following error codes are send to the terminal, the bootloader status
560 61 zero_gravi
LED is permanently activated and the system must be manually reset.
561 60 zero_gravi
 
562
[cols="<2,<13"]
563
[grid="rows"]
564
|=======================
565 62 zero_gravi
| **`ERROR_0`** | If you try to transfer an invalid executable (via UART or from the external SPI flash), this error message shows up. There might be a transfer protocol configuration error in the terminal program. Also, if no SPI flash was found during an auto-boot attempt, this message will be displayed.
566
| **`ERROR_1`** | Your program is way too big for the internal processor’s instructions memory. Increase the memory size or reduce your application code.
567 60 zero_gravi
| **`ERROR_2`** | This indicates a checksum error. Something went wrong during the transfer of the program image (upload via UART or loading from the external SPI flash). If the error was caused by a UART upload, just try it again. When the error was generated during a flash access, the stored image might be corrupted.
568
| **`ERROR_3`** | This error occurs if the attached SPI flash cannot be accessed. Make sure you have the right type of flash and that it is properly connected to the NEORV32 SPI port using chip select #0.
569 66 zero_gravi
| **`ERR 0x???????? 0x???????? 0x????????`** | The bootloader encountered an exception during operation. This might be caused when it tries to access peripherals that were not implemented during synthesis. Example: executing `l` or `s` (SPI flash operations) without the SPI module beeing implemented.
570 60 zero_gravi
|=======================
571
 
572
 
573
 
574
<<<
575
// ####################################################################################################################
576
:sectnums:
577
=== NEORV32 Runtime Environment
578
 
579
The NEORV32 provides a minimal runtime environment (RTE) that takes care of a stable
580
and _safe_ execution environment by handling _all_ traps (including interrupts).
581
 
582
[NOTE]
583
Using the RTE is **optional**. The RTE provides a simple and comfortable way of delegating traps while making sure that all traps (even though they are not
584
explicitly used by the application) are handled correctly. Performance-optimized applications or embedded operating systems should not use the RTE for delegating traps.
585
 
586
When execution enters the application's `main` function, the actual runtime environment is responsible for catching all implemented exceptions
587
and interrupts. To activate the NEORV32 RTE execute the following function:
588
 
589
[source,c]
590
----
591
void neorv32_rte_setup(void);
592
----
593
 
594
This setup initializes the `mtvec` CSR, which provides the base entry point for all trap
595
handlers. The address stored to this register reflects the first-level exception handler provided by the
596
NEORV32 RTE. Whenever an exception or interrupt is triggered, this first-level handler is called.
597
 
598
The first-level handler performs a complete context save, analyzes the source of the exception/interrupt and
599
calls the according second-level exception handler, which actually takes care of the exception/interrupt
600
handling. For this, the RTE manages a private look-up table to store the addresses of the according trap
601
handlers.
602
 
603
After the initial setup of the RTE, each entry in the trap handler's look-up table is initialized with a debug
604
handler, that outputs detailed hardware information via the **primary UART (UART0)** when triggered. This
605
is intended as a fall-back for debugging or for accidentally-triggered exceptions/interrupts.
606 66 zero_gravi
For instance, an illegal instruction exception caught by the RTE debug handler might look like this in the UART0 output:
607 60 zero_gravi
 
608
[source]
609
----
610 68 zero_gravi
 Illegal instruction @ PC=0x000002d6, MTVAL=0x00001537 
611 60 zero_gravi
----
612
 
613 68 zero_gravi
For bus access faults the RTE also outputs the error code from the <<_internal_bus_monitor_buskeeper>>
614
to show the cause of the access fault. Two example are shown below.
615
 
616
[source]
617
----
618
 Load access fault [TIMEOUT_ERR] @ PC=0x00000150, MTVAL=0xFFFFFF70 
619
 Store access fault [DEVICE_ERR] @ PC=0x00000162, MTVAL=0xF0000000 
620
----
621
 
622 60 zero_gravi
To install the **actual application's trap handlers** the NEORV32 RTE provides functions for installing and
623
un-installing trap handler for each implemented exception/interrupt source.
624
 
625
[source,c]
626
----
627
int neorv32_rte_exception_install(uint8_t id, void (*handler)(void));
628
----
629
 
630
[cols="<5,<12"]
631
[options="header",grid="rows"]
632
|=======================
633
| ID name [C] | Description / trap causing entry
634
| `RTE_TRAP_I_MISALIGNED` | instruction address misaligned
635
| `RTE_TRAP_I_ACCESS`     | instruction (bus) access fault
636
| `RTE_TRAP_I_ILLEGAL`    | illegal instruction
637
| `RTE_TRAP_BREAKPOINT`   | breakpoint (`ebreak` instruction)
638
| `RTE_TRAP_L_MISALIGNED` | load address misaligned
639
| `RTE_TRAP_L_ACCESS`     | load (bus) access fault
640
| `RTE_TRAP_S_MISALIGNED` | store address misaligned
641
| `RTE_TRAP_S_ACCESS`     | store (bus) access fault
642
| `RTE_TRAP_MENV_CALL`    | environment call from machine mode (`ecall` instruction)
643
| `RTE_TRAP_UENV_CALL`    | environment call from user mode (`ecall` instruction)
644
| `RTE_TRAP_MTI`          | machine timer interrupt
645
| `RTE_TRAP_MEI`          | machine external interrupt
646
| `RTE_TRAP_MSI`          | machine software interrupt
647
| `RTE_TRAP_FIRQ_0` : `RTE_TRAP_FIRQ_15` | fast interrupt channel 0..15
648
|=======================
649
 
650
When installing a custom handler function for any of these exception/interrupts, make sure the function uses
651
**no attributes** (especially no interrupt attribute!), has no arguments and no return value like in the following
652
example:
653
 
654
[source,c]
655
----
656
void handler_xyz(void) {
657
 
658
  // handle exception/interrupt...
659
}
660
----
661
 
662
[WARNING]
663
Do NOT use the `((interrupt))` attribute for the application exception handler functions! This
664
will place an `mret` instruction to the end of it making it impossible to return to the first-level
665
exception handler of the RTE, which will cause stack corruption.
666
 
667
Example: Installation of the MTIME interrupt handler:
668
 
669
[source,c]
670
----
671
neorv32_rte_exception_install(EXC_MTI, handler_xyz);
672
----
673
 
674
To remove a previously installed exception handler call the according un-install function from the NEORV32
675
runtime environment. This will replace the previously installed handler by the initial debug handler, so even
676
un-installed exceptions and interrupts are further captured.
677
 
678
[source,c]
679
----
680
int neorv32_rte_exception_uninstall(uint8_t id);
681
----
682
 
683
Example: Removing the MTIME interrupt handler:
684
 
685
[source,c]
686
----
687
neorv32_rte_exception_uninstall(EXC_MTI);
688
----
689
 
690
[TIP]
691
More information regarding the NEORV32 runtime environment can be found in the doxygen
692
software documentation (also available online at https://stnolting.github.io/neorv32/sw/files.html[GitHub pages]).

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.