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

Subversion Repositories neorv32

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

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 72 zero_gravi
To make actual use of the NEORV32 processor, the project comes with a complete software ecosystem. This
5 60 zero_gravi
ecosystem is based on the RISC-V port of the GCC GNU Compiler Collection and consists of the following elementary parts:
6
 
7 72 zero_gravi
* <<_compiler_toolchain>>
8
* <<_core_libraries>>
9
* <<_application_makefile>>
10
* <<_executable_image_format>>
11
** <<_linker_script>>
12
** <<_ram_layout>>
13
** <<_c_standard_library>>
14
** <<_start_up_code_crt0>>
15
* <<_bootloader>>
16
* <<_neorv32_runtime_environment>>
17
 
18
A summarizing list of the most important elements of the software framework and their according
19
files and folders is shown below:
20
 
21 60 zero_gravi
[cols="<6,<4"]
22
[grid="none"]
23
|=======================
24 72 zero_gravi
| Application start-up code               | `sw/common/crt0.S`
25
| Application linker script               | `sw/common/neorv32.ld`
26
| Core hardware driver libraries ("HAL")  | `sw/lib/include/` & `sw/lib/source/`
27
| Central application makefile            | `sw/common/common.mk`
28
| Tool for generating NEORV32 executables | `sw/image_gen/`
29
| Default bootloader                      | `sw/bootloader/bootloader.c`
30
| Example programs                        | `sw/example`
31 60 zero_gravi
|=======================
32
 
33 72 zero_gravi
.Software Documentation
34
[TIP]
35
All core libraries and example programs are highly documented using **Doxygen**.
36
See section <>.
37
The documentation is automatically built and deployed to GitHub pages and is available online
38
at https://stnolting.github.io/neorv32/sw/files.html .
39 60 zero_gravi
 
40 72 zero_gravi
 
41
 
42 60 zero_gravi
// ####################################################################################################################
43
:sectnums:
44
=== Compiler Toolchain
45
 
46
The toolchain for this project is based on the free RISC-V GCC-port. You can find the compiler sources and
47
build instructions on the official RISC-V GNU toolchain GitHub page: https://github.com/riscv/riscv-gnutoolchain.
48
 
49 72 zero_gravi
The NEORV32 implements a 32-bit RISC-V architecture and uses a 32-bit integer and soft-float ABI by default.
50
Make sure the toolchain / toolchain build is configured accordingly.
51 60 zero_gravi
 
52 72 zero_gravi
* MARCH = `rv32i`
53
* MABI = `ilp32`
54
 
55 60 zero_gravi
Alternatively, you can download my prebuilt `rv32i/e` toolchains for 64-bit x86 Linux from: https://github.com/stnolting/riscv-gcc-prebuilt
56
 
57 72 zero_gravi
The default toolchain prefix used by the project's makefiles is **`riscv32-unknown-elf`**, which can be changes
58
using makefile flags at any time.
59 60 zero_gravi
 
60
[TIP]
61
More information regarding the toolchain (building from scratch or downloading the prebuilt ones)
62 61 zero_gravi
can be found in the user guides' section https://stnolting.github.io/neorv32/ug/#_software_toolchain_setup[Software Toolchain Setup].
63 60 zero_gravi
 
64
 
65
 
66
<<<
67
// ####################################################################################################################
68
:sectnums:
69
=== Core Libraries
70
 
71 72 zero_gravi
The NEORV32 project provides a set of C libraries that allows an easy usage of the processor/CPU features
72
(also called "HAL" - hardware abstraction layer). All driver and runtime-related files are located in
73
`sw/lib`. These are automatically included and linked by adding the following _include statement_:
74 60 zero_gravi
 
75
[source,c]
76
----
77 72 zero_gravi
#include  // add NEORV32 HAL and runtime libraries
78 60 zero_gravi
----
79
 
80
[cols="<3,<4,<8"]
81
[options="header",grid="rows"]
82
|=======================
83
| C source file | C header file | Description
84 72 zero_gravi
| -                   | `neorv32.h`            | main NEORV32 definitions and library file
85
| `neorv32_cfs.c`     | `neorv32_cfs.h`        | HW driver (stubs) functions for the custom functions subsystem
86
footnote:[This driver file only represents a stub, since the real CFS drivers are defined by the actual CFS implementation.]
87
| `neorv32_cpu.c`     | `neorv32_cpu.h`        | HW driver functions for the NEORV32 **CPU**
88
| `neorv32_cpu_cfu.c` | `neorv32_cpu_cfu.h`    | HW driver functions for the NEORV32 **CFU** (custom instructions)
89
| `neorv32_gpio.c`    | `neorv32_gpio.h`       | HW driver functions for the **GPIO**
90
| `neorv32_gptmr.c`   | `neorv32_gptmr.h`      | HW driver functions for the **GPTRM**
91
| -                   | `neorv32_intrinsics.h` | macros for custom intrinsics & instructions
92
| `neorv32_mtime.c`   | `neorv32_mtime.h`      | HW driver functions for the **MTIME**
93
| `neorv32_neoled.c`  | `neorv32_neoled.h`     | HW driver functions for the **NEOLED**
94
| `neorv32_pwm.c`     | `neorv32_pwm.h`        | HW driver functions for the **PWM**
95
| `neorv32_rte.c`     | `neorv32_rte.h`        | NEORV32 **runtime environment** and helper functions
96
| `neorv32_slink.c`   | `neorv32_slink.h`      | HW driver functions for the **SLINK**
97
| `neorv32_spi.c`     | `neorv32_spi.h`        | HW driver functions for the **SPI**
98
| `neorv32_trng.c`    | `neorv32_trng.h`       | HW driver functions for the **TRNG**
99
| `neorv32_twi.c`     | `neorv32_twi.h`        | HW driver functions for the **TWI**
100
| `neorv32_uart.c`    | `neorv32_uart.h`       | HW driver functions for the **UART0** and **UART1**
101
| `neorv32_wdt.c`     | `neorv32_wdt.h`        | HW driver functions for the **WDT**
102
| `neorv32_xip.c`     | `neorv32_xip.h`        | HW driver functions for the **XIP**
103
| `neorv32_xirq.c`    | `neorv32_xirq.h`       | HW driver functions for the **XIRQ**
104
| `syscalls.c`        | -                      | newlib system calls
105 60 zero_gravi
|=======================
106
 
107
[TIP]
108 72 zero_gravi
A CMSIS-SVD-compatible **System View Description (SVD)** file including all peripherals is available in `sw/svd`.
109
`sw/lib/include`. Currently, the following library files are available:
110 60 zero_gravi
 
111
 
112
 
113
<<<
114
// ####################################################################################################################
115
:sectnums:
116
=== Application Makefile
117
 
118 62 zero_gravi
Application compilation is based on a single, centralized **GNU makefiles** `sw/common/common.mk`. Each project in the
119 72 zero_gravi
`sw/example` folder features a makefile that just includes this central makefile. When creating a new project copy an
120
existing project folder or at least the makefile to the new project folder. It is suggested to create new projects also
121
in `sw/example` to keep the file dependencies. However, these dependencies can be manually configured via makefiles
122
variables when the new project is located somewhere else.
123 60 zero_gravi
 
124 62 zero_gravi
[NOTE]
125 72 zero_gravi
Before the makefile can be used to compile applications, the RISC-V GCC toolchain needs to be installed. Furthermore,
126
the `bin` folder of the compiler needs to be added to the system's `PATH` variable. More information can be found in
127 62 zero_gravi
https://stnolting.github.io/neorv32/ug/#_software_toolchain_setup[User Guide: Software Toolchain Setup].
128 60 zero_gravi
 
129 72 zero_gravi
The makefile is invoked by simply executing `make` in the console. For example:
130 60 zero_gravi
 
131
[source,bash]
132
----
133
neorv32/sw/example/blink_led$ make
134
----
135
 
136
:sectnums:
137
==== Targets
138
 
139 62 zero_gravi
Just executing `make` (or executing `make help`) will show the help menu listing all available targets.
140 60 zero_gravi
 
141 62 zero_gravi
[source,makefile]
142
----
143
$ make
144 69 zero_gravi
<<< NEORV32 SW Application Makefile >>>
145 62 zero_gravi
Make sure to add the bin folder of RISC-V GCC to your PATH variable.
146 69 zero_gravi
 
147
== Targets ==
148
 help         - show this text
149
 check        - check toolchain
150
 info         - show makefile/toolchain configuration
151
 exe          - compile and generate  executable for upload via bootloader
152
 hex          - compile and generate  executable raw file
153
 image        - compile and generate VHDL IMEM boot image (for application) in local folder
154
 install      - compile, generate and install VHDL IMEM boot image (for application)
155
 sim          - in-console simulation using default/simple testbench and GHDL
156
 all          - exe + hex + install
157
 elf_info     - show ELF layout info
158
 clean        - clean up project
159
 clean_all    - clean up project, core libraries and image generator
160
 bl_image     - compile and generate VHDL BOOTROM boot image (for bootloader only!) in local folder
161
 bootloader   - compile, generate and install VHDL BOOTROM boot image (for bootloader only!)
162
 
163
== Variables ==
164
 USER_FLAGS   - Custom toolchain flags [append only], default ""
165
 EFFORT       - Optimization level, default "-Os"
166
 MARCH        - Machine architecture, default "rv32i"
167
 MABI         - Machine binary interface, default "ilp32"
168
 APP_INC      - C include folder(s) [append only], default "-I ."
169
 ASM_INC      - ASM include folder(s) [append only], default "-I ."
170
 RISCV_PREFIX - Toolchain prefix, default "riscv32-unknown-elf-"
171
 NEORV32_HOME - NEORV32 home folder, default "../../.."
172 62 zero_gravi
----
173 60 zero_gravi
 
174
 
175
:sectnums:
176
==== Configuration
177
 
178 72 zero_gravi
The compilation flow is configured via variables right at the beginning of the central
179 62 zero_gravi
makefile (`sw/common/common.mk`):
180 60 zero_gravi
 
181 62 zero_gravi
[TIP]
182 72 zero_gravi
The makefile configuration variables can be overridden or extended directly when invoking the makefile. For
183
example `$ make MARCH=rv32ic clean_all exe` overrides the default `MARCH` variable definitions.
184
Permanent modifications/definitions can be made in the project-local makefile
185
(e.g., `sw/example/blink_led/makefile`).
186 62 zero_gravi
 
187 72 zero_gravi
.Default Makefile Configuration
188 60 zero_gravi
[source,makefile]
189
----
190
# *****************************************************************************
191
# USER CONFIGURATION
192
# *****************************************************************************
193
# User's application sources (*.c, *.cpp, *.s, *.S); add additional files here
194
APP_SRC ?= $(wildcard ./*.c) $(wildcard ./*.s) $(wildcard ./*.cpp) $(wildcard ./*.S)
195
# User's application include folders (don't forget the '-I' before each entry)
196
APP_INC ?= -I .
197
# User's application include folders - for assembly files only (don't forget the '-I' before each
198
entry)
199
ASM_INC ?= -I .
200
# Optimization
201
EFFORT ?= -Os
202
# Compiler toolchain
203 62 zero_gravi
RISCV_PREFIX ?= riscv32-unknown-elf-
204 60 zero_gravi
# CPU architecture and ABI
205 65 zero_gravi
MARCH ?= rv32i
206
MABI  ?= ilp32
207 60 zero_gravi
# User flags for additional configuration (will be added to compiler flags)
208
USER_FLAGS ?=
209
# Relative or absolute path to the NEORV32 home folder
210
NEORV32_HOME ?= ../../..
211
# *****************************************************************************
212
----
213
 
214 72 zero_gravi
.Variables Description
215 60 zero_gravi
[cols="<3,<10"]
216
[grid="none"]
217
|=======================
218 72 zero_gravi
| `APP_SRC`      | The source files of the application (`*.c`, `*.cpp`, `*.S` and `*.s` files are allowed;
219
files of these types in the project folder are automatically added via wild cards). Additional files can be added separated by white spaces
220
| `APP_INC`      | Include file folders; separated by white spaces; must be defined with `-I` prefix
221
| `ASM_INC`      | Include file folders that are used only for the assembly source files (`*.S`/`*.s`).
222
| `EFFORT`       | Optimization level, optimize for size (`-Os`) is default; legal values: `-O0`, `-O1`, `-O2`, `-O3`, `-Os`, `-Ofast`, ...
223
| `RISCV_PREFIX` | The toolchain prefix to be used; follows the triplet naming convention `[architecture]-[host_system]-[output]-...`
224
| `MARCH`        | The targeted RISC-V architecture/ISA; enable compiler support of optional CPU extension by adding the according extension
225
name (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]
226
for more information
227
| `MABI`         | Application binary interface (default: 32-bit integer ABI `ilp32`)
228
| `USER_FLAGS`   | Additional flags that will be forwarded to the compiler tools
229
| `NEORV32_HOME` | Relative or absolute path to the NEORV32 project home folder; adapt this if the makefile/project is not in the project's
230
default `sw/example` folder
231 60 zero_gravi
|=======================
232
 
233
:sectnums:
234
==== Default Compiler Flags
235
 
236
The following default compiler flags are used for compiling an application. These flags are defined via the
237 72 zero_gravi
`CC_OPTS` variable. Custom flags can be _appended_ to it using the `USER_FLAGS` variable.
238 60 zero_gravi
 
239
[cols="<3,<9"]
240
[grid="none"]
241
|=======================
242 72 zero_gravi
| `-Wall`                  | Enable all compiler warnings.
243
| `-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.
244
| `-nostartfiles`          | Do not use the default start code. Instead, use the NEORV32-specific start-up code (`sw/common/crt0.S`).
245
| `-Wl,--gc-sections`      | Make the linker perform dead code elimination.
246
| `-lm`                    | Include/link with `math.h`.
247
| `-lc`                    | Search for the standard C library when linking.
248
| `-lgcc`                  | Make sure we have no unresolved references to internal GCC library subroutines.
249
| `-mno-fdiv`              | Use built-in software functions for floating-point divisions and square roots (since the according instructions are not supported yet).
250 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.
251
| `-falign-labels=4`
252
| `-falign-loops=4`
253
| `-falign-jumps=4`
254
|=======================
255
 
256
 
257
 
258
<<<
259
// ####################################################################################################################
260
:sectnums:
261
=== Executable Image Format
262
 
263 61 zero_gravi
In order to generate a file, which can be executed by the processor, all source files have to be compiler, linked
264
and packed into a final _executable_.
265 60 zero_gravi
 
266 61 zero_gravi
:sectnums:
267
==== Linker Script
268
 
269
When all the application sources have been compiled, they need to be _linked_ in order to generate a unified
270
program file. For this purpose the makefile uses the NEORV32-specific linker script `sw/common/neorv32.ld` for
271
linking all object files that were generated during compilation.
272
 
273
The linker script defines three memory _sections_: `rom`, `ram` and `iodev`. Each section provides specific
274
access _attributes_: read access (`r`), write access (`w`) and executable (`x`).
275
 
276
.Linker memory sections - general
277 60 zero_gravi
[cols="<2,^1,<7"]
278
[options="header",grid="rows"]
279
|=======================
280
| Memory section  | Attributes | Description
281 61 zero_gravi
| `ram`           | `rwx`      | Data memory address space (processor-internal/external DMEM)
282
| `rom`           | `rx`       | Instruction memory address space (processor-internal/external IMEM) _or_ internal bootloader ROM
283
| `iodev`         | `rw`       | Processor-internal memory-mapped IO/peripheral devices address space
284 60 zero_gravi
|=======================
285
 
286 61 zero_gravi
These sections are defined right at the beginning of the linker script:
287 60 zero_gravi
 
288 61 zero_gravi
.Linker memory sections - cut-out from linker script `neorv32.ld`
289
[source,c]
290
----
291
MEMORY
292
{
293
  ram  (rwx) : ORIGIN = 0x80000000, LENGTH = DEFINED(make_bootloader) ? 512 : 8*1024
294
  rom   (rx) : ORIGIN = DEFINED(make_bootloader) ? 0xFFFF0000 : 0x00000000, LENGTH = DEFINED(make_bootloader) ? 32K : 2048M
295
  iodev (rw) : ORIGIN = 0xFFFFFE00, LENGTH = 512
296
}
297
----
298 60 zero_gravi
 
299 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
300 72 zero_gravi
fixed and should not be altered. The base addresses and sizes of the `ram` and `rom` regions correspond to the total available instruction
301
and data memory address space (see section <<_address_space_layout>>) as defined in `rtl/core/neorv32_package.vhd`.
302 60 zero_gravi
 
303 61 zero_gravi
[IMPORTANT]
304 72 zero_gravi
`ORIGIN` of the `ram` section has to be always identical to the processor's `dspace_base_c` hardware configuration. +
305
 +
306 61 zero_gravi
`ORIGIN` of the `rom` section has to be always identical to the processor's `ispace_base_c` hardware configuration.
307
 
308
The sizes of `rom` section is a little bit more complicated. The default linker script configuration assumes a _maximum_ of 2GB _logical_
309 72 zero_gravi
memory space, which is also the default configuration of the processor's hardware instruction memory address space. This size does not have
310 61 zero_gravi
to reflect the _actual_ physical size of the instruction memory (internal IMEM and/or processor-external memory). It just provides a maximum
311
limit. When uploading new executable via the bootloader, the bootloader itself checks if sufficient _physical_ instruction memory is available.
312
If a new executable is embedded right into the internal-IMEM the synthesis tool will check, if the configured instruction memory size
313
is sufficient (e.g., via the <<_mem_int_imem_size>> generic).
314
 
315
[IMPORTANT]
316
The `rom` region uses a conditional assignment (via the `make_bootloader` symbol) for `ORIGIN` and `LENGTH` that is used to place
317
"normal executable" (i.e. for the IMEM) or "the bootloader image" to their according memories. +
318
 +
319
The `ram` region also uses a conditional assignment (via the `make_bootloader` symbol) for `LENGTH`. When compiling the bootloader
320
(`make_bootloader` symbol is set) the generated bootloader will only use the _first_ 512 bytes of the data address space. This is
321
a fall-back to ensure the bootloader can operate independently of the actual _physical_ data memory size.
322
 
323 72 zero_gravi
The linker maps all the regions from the compiled object files into five final sections: `.text`, `.rodata`, `.data`, `.bss` and `.heap`.
324
These regions contain everything required for the application to run:
325 61 zero_gravi
 
326
.Linker memory regions
327 60 zero_gravi
[cols="<1,<9"]
328
[options="header",grid="rows"]
329
|=======================
330 62 zero_gravi
| Region    | Description
331 60 zero_gravi
| `.text`   | Executable instructions generated from the start-up code and all application sources.
332
| `.rodata` | Constants (like strings) from the application; also the initial data for initialized variables.
333
| `.data`   | This section is required for the address generation of fixed (= global) variables only.
334
| `.bss`    | This section is required for the address generation of dynamic memory constructs only.
335 72 zero_gravi
| `.heap`   | This section is required for the address generation of dynamic memory constructs only.
336 60 zero_gravi
|=======================
337
 
338 72 zero_gravi
The `.text` and `.rodata` sections are mapped to processor's instruction memory space and the `.data`,
339
`.bss` and `heap` sections are mapped to the processor's data memory space. Finally, the `.text`, `.rodata` and `.data`
340 61 zero_gravi
sections are extracted and concatenated into a single file `main.bin`.
341 60 zero_gravi
 
342
 
343 61 zero_gravi
:sectnums:
344 72 zero_gravi
==== RAM Layout
345
 
346
The default NEORV32 linker script uses all of the defined RAM (linker script memory section `ram`) to create four areas.
347
Note that depending on the application some areas might not be existent at all.
348
 
349
.Default RAM Layout
350
image::ram_layout.png[400]
351
 
352
[start=1]
353
. **Constant data (`.data`)**: The constant data section is placed right at the beginning of the RAM. For example, this section
354
contains _explicitly initialized_ global variables. This section is initialized by the executable.
355
. **Dynamic data (`.bss`)**: The constant data section is followed by the dynamic data section, which contains _uninitialized_ data
356
like global variables without explicit initialization. This section is cleared by the start-up code `crt0.S`.
357
. **Heap (`.heap`)**: The heap is used for dynamic memory that is managed by functions like `malloc()` and `free()`. The heap
358
grows upwards. This section is not initialized at all.
359
. **Stack**: The stack starts at the very end of the RAM at address `ORIGIN(ram) + LENGTH(ram) - 4`. The stack grows downwards.
360
 
361
There is _no explicit limit_ for the maximum stack size as this is hard to check. However, a physical memory protection rule could
362
be used to configure a maximum size by adding a "protection area" between stack and heap (a PMP region without any access rights).
363
 
364
The maximum size of the heap is defined by the linker script's `__heap_size` symbol. This symbol can be overridden at any time.
365
By default, the maximum heap size is 1/4 of the total RAM size.
366
 
367
.Heap-Stack Collisions
368
[WARNING]
369
Take care when using dynamic memory to avoid collision of the heap and stack memory areas. There is no compile-time protection
370
mechanism available as the actual heap and stack size are defined by _runtime_ data. Also beware of fragmentation when
371
using dynamic memory allocation.
372
 
373
 
374
:sectnums:
375
==== C Standard Library
376
 
377
.Constructors and Deconstructors
378
[IMPORTANT]
379
The NEORV32 processor is an embedded system intended for running bare-metal or RTOS applications. To simplify this setup
380
explicit constructors and deconstructors are not supported by default. However, a minimal "deconstructor-alike" support is
381
provided by the <<_after_main_handler>>.
382
 
383
The NEORV32 is a processor for _embedded_ applications. Hence, it is not capable of running desktop OSs like Linux
384
(at least not without emulation). Hence, the software framework relies on a "bare-metal" setup that uses **newlib**
385
as default C standard library.
386
 
387
.RTOS Support
388
[NOTE]
389
The NEORV32 CPU and processor **do support** embedded RTOS like FreeRTOS and Zephyr. See the User guide section
390
https://stnolting.github.io/neorv32/ug/#_zephyr_rtos_support[Zephyr RTOS Support] and
391
https://stnolting.github.io/neorv32/ug/#_freertos_support[FreeRTOS Support]
392
for more information.
393
 
394
Newlib provides stubs for common "system calls" (like file handling and standard input/output) that are used by other
395
C libraries like `stdio`. These stubs are available in `sw/source/syscalls.c` and were adapted for the NEORV32 processor.
396
 
397
.Standard Console(s)
398
[NOTE]
399
<<_primary_universal_asynchronous_receiver_and_transmitter_uart0, UART0>>
400
is used to implement all the standard input, output and error consoles (`STDIN`, `STDOUT` and `STDERR`).
401
 
402
.Newlib Test/Demo Program
403
[TIP]
404
A simple test and demo program, which uses some of newlib's core functions (like `malloc`/`free` and `read`/`write`)
405
is available in `sw/example_newlib_demo`
406
 
407
 
408
:sectnums:
409 61 zero_gravi
==== Executable Image Generator
410 60 zero_gravi
 
411 61 zero_gravi
The `main.bin` file is packed by the NEORV32 image generator (`sw/image_gen`) to generate the final executable file.
412
 
413
[NOTE]
414
The sources of the image generator are automatically compiled when invoking the makefile.
415
 
416
The image generator can generate three types of executables, selected by a flag when calling the generator:
417
 
418 60 zero_gravi
[cols="<1,<9"]
419
[grid="none"]
420
|=======================
421
| `-app_bin` | Generates an executable binary file `neorv32_exe.bin` (for UART uploading via the bootloader).
422 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).
423 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.
424
| `-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.
425
|=======================
426
 
427 61 zero_gravi
All these options are managed by the makefile. The _normal application_ compilation flow will generate the `neorv32_exe.bin`
428
executable to be upload via UART to the NEORV32 bootloader.
429 60 zero_gravi
 
430 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
431
beginning of the file. The first word of the executable is the signature word and is always `0x4788cafe`. Based on this word the bootloader
432
can identify a valid image file. The next word represents the size in bytes of the actual program
433 60 zero_gravi
image in bytes. A simple "complement" checksum of the actual program image is given by the third word. This
434
provides a simple protection against data transmission or storage errors.
435
 
436
 
437 61 zero_gravi
:sectnums:
438
==== Start-Up Code (crt0)
439 60 zero_gravi
 
440 61 zero_gravi
The CPU and also the processor require a minimal start-up and initialization code to bring the CPU (and the SoC)
441
into a stable and initialized state and to initialize the C runtime environment before the actual application can be executed.
442
This start-up code is located in `sw/common/crt0.S` and is automatically linked _every_ application program
443
and placed right before the actual application code so it gets executed right after reset.
444 60 zero_gravi
 
445 61 zero_gravi
The `crt0.S` start-up performs the following operations:
446 60 zero_gravi
 
447 61 zero_gravi
[start=1]
448 73 zero_gravi
. Initialize all integer registers `x1 - x31` (or just `x1 - x15` when using the `E` CPU extension) to a defined value.
449
. Initialize the global pointer `gp` and the stack pointer `sp` according to the <<_ram_layout>> provided by the linker script.
450
. Initialize all CPU core CSRs and also install a default "dummy" trap handler for _all_ traps. This handler catches all traps
451
during the early boot phase.
452
. All interrupt sources are disabled and all pending interrupts are cleared.
453
. Clear all counter CSRs and stop auto-increment.
454
. Clear IO area: Write zero to all memory-mapped registers within the IO region (`iodev` section). If certain devices have not
455
been implemented, a bus access fault exception will occur. This exception is captured by the dummy trap handler.
456 61 zero_gravi
. Clear the `.bss` section defined by the linker script.
457
. Copy read-only data from the `.text` section to the `.data` section to set initialized variables.
458
. Call the application's `main` function (with _no_ arguments: `argc` = `argv` = 0).
459 73 zero_gravi
. If the main function returns...
460
** the return value is copied to the <<_mscratch>> CSR to allow inspection by the on-chip debugger.
461
** an optional <<_after_main_handler>> is called (if defined at all).
462
** the last step the CPU does is entering endless sleep mode (using the `wfi` instruction).
463 60 zero_gravi
 
464 61 zero_gravi
:sectnums:
465
===== After-Main Handler
466
 
467 73 zero_gravi
If the application's `main()` function actually returns, an _after main handler_ can be executed. This handler is a "normal" function
468
as the C runtime is still available when executed. If this handler uses any kind of peripheral/IO modules make sure these are
469
already initialized within the application. Otherwise you have to initialize them _inside_ the handler.
470 61 zero_gravi
 
471
.After-main handler - function prototype
472
[source,c]
473
----
474 73 zero_gravi
void __neorv32_crt0_after_main(int32_t return_code);
475 61 zero_gravi
----
476
 
477
The function has exactly one argument (`return_code`) that provides the _return value_ of the application's main function.
478 73 zero_gravi
For instance, this variable contains `-1` if the main function returned with `return -1;`. The after-main handler itself does
479
not provide a return value.
480 61 zero_gravi
 
481 73 zero_gravi
A simple UART output can be used to inform the user when the application's main function returns
482 61 zero_gravi
(this example assumes that UART0 has been already properly configured in the actual application):
483
 
484 72 zero_gravi
.After-main handler - simple example
485 61 zero_gravi
[source,c]
486
----
487 73 zero_gravi
void __neorv32_crt0_after_main(int32_t return_code) {
488 61 zero_gravi
 
489 72 zero_gravi
  neorv32_uart0_printf("\n main function returned with exit code %i. \n", return_code); <1>
490 61 zero_gravi
}
491
----
492 72 zero_gravi
<1> Use `` here to make clear this is a message comes from the runtime environment.
493 61 zero_gravi
 
494
 
495 60 zero_gravi
<<<
496
// ####################################################################################################################
497
 
498 72 zero_gravi
include::software_bootloader.adoc[]
499 60 zero_gravi
 
500
 
501
 
502
<<<
503
// ####################################################################################################################
504
 
505 72 zero_gravi
include::software_rte.adoc[]

powered by: WebSVN 2.1.0

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