[docs] cleanup bootloader user guide

This commit is contained in:
stnolting 2025-04-05 17:17:37 +02:00
parent 7f72f3d6ce
commit 7a5bef2f98
4 changed files with 83 additions and 153 deletions

View file

@ -20,8 +20,8 @@ which provides **SoC setups** for various FPGAs, boards and toolchains.
<<_installing_an_executable_directly_into_memory, persistent>> in internal memory
* setup a new <<_setup_of_a_new_application_program_project, application project>>
* <<_application_specific_processor_configuration, optimizing>> the core for your application
* add <<_adding_custom_hardware_modules, custom hardware extensions>> and <<_customizing_the_internal_bootloader, customizing the bootloader>>
* <<_programming_an_external_spi_flash_via_the_bootloader, program>> an external SPI flash for persistent application storage
* add <<_adding_custom_hardware_modules, custom hardware extensions>>
* <<_using_the_neorv32_bootloader>>
* generate an AMD Vivado <<_packaging_the_processor_as_vivado_ip_block, IP block>>
* <<_simulating_the_processor, simulate>> the processor and <<_building_the_documentation, build the documentation>>
* RTOS support for <<_zephyr_rtos_support, Zephyr>> and <<_freertos_support, FreeRTOS>>
@ -49,9 +49,7 @@ include::application_specific_configuration.adoc[]
include::adding_custom_hw_modules.adoc[]
include::customizing_the_bootloader.adoc[]
include::programming_an_external_spi_flash_via_bootloader.adoc[]
include::using_the_neorv32_bootloader.adoc[]
include::packaging_vivado.adoc[]

View file

@ -1,79 +0,0 @@
<<<
:sectnums:
== Customizing the Internal Bootloader
The NEORV32 bootloader provides several options to configure and customize it for a certain application setup.
This configuration is done by passing _defines_ when compiling the bootloader. Of course you can also
modify to bootloader source code to provide a setup that perfectly fits your needs.
[IMPORTANT]
Each time the bootloader sources are modified, the bootloader has to be re-compiled (and re-installed to the
bootloader ROM) and the processor has to be re-synthesized.
[NOTE]
Keep in mind that the maximum size for the bootloader is limited to 8kB and it should be compiled using the
minimal base & privileged ISA `rv32e_zicsr_zifencei` only to ensure it can work with any actual CPU configuration.
.Bootloader configuration parameters
[cols="<2,^1,^2,<6"]
[options="header", grid="rows"]
|=======================
| Parameter | Default | Legal values | Description
4+^| Memory layout
| `EXE_BASE_ADDR` | `0x00000000` | _any_ | Base address / boot address for the executable (see section "Address Space" in the NEORV32 data sheet)
4+^| Serial console interface
| `UART_EN` | `1` | `0`, `1` | Set to `0` to disable UART0 (no serial console at all)
| `UART_BAUD` | `19200` | _any_ | Baud rate of UART0
| `UART_HW_HANDSHAKE_EN` | `0` | `0`, `1` | Set to `1` to enable UART0 hardware flow control
4+^| Status LED
| `STATUS_LED_EN` | `1` | `0`, `1` | Enable bootloader status led ("heart beat") at `GPIO` output port pin #`STATUS_LED_PIN` when `1`
| `STATUS_LED_PIN` | `0` | `0` ... `31` | `GPIO` output pin used for the high-active status LED
4+^| Auto-boot configuration
| `AUTO_BOOT_TIMEOUT` | `10` | _any_ | Time in seconds after the auto-boot sequence starts (if there is no UART input by the user); set to 0 to disabled auto-boot sequence
4+^| SPI configuration
| `SPI_EN` | `1` | `0`, `1` | Set `1` to enable the usage of the SPI module (including load/store executables from/to SPI flash options)
| `SPI_FLASH_CS` | `0` | `0` ... `7` | SPI chip select output (`spi_csn_o`) for selecting flash
| `SPI_FLASH_ADDR_BYTES` | `3` | `2`, `3`, `4` | SPI flash address size in number of bytes (2=16-bit, 3=24-bit, 4=32-bit)
| `SPI_FLASH_SECTOR_SIZE` | `65536` | _any_ | SPI flash sector size in bytes
| `SPI_FLASH_CLK_PRSC` | `CLK_PRSC_8` | `CLK_PRSC_2` `CLK_PRSC_4` `CLK_PRSC_8` `CLK_PRSC_64` `CLK_PRSC_128` `CLK_PRSC_1024` `CLK_PRSC_2024` `CLK_PRSC_4096` | SPI clock pre-scaler (dividing main processor clock)
| `SPI_BOOT_BASE_ADDR` | `0x00400000` | _any_ 32-bit value | Defines the _base_ address of the executable in external flash
4+^| TWI configuration
| `TWI_EN` | `0` | `0`, `1` | Set `1` to enable the usage of the TWI module (including load executables from TWI device option)
| `TWI_CLK_PRSC` | `CLK_PRSC_64` | `CLK_PRSC_2` `CLK_PRSC_4` `CLK_PRSC_8` `CLK_PRSC_64` `CLK_PRSC_128` `CLK_PRSC_1024` `CLK_PRSC_2024` `CLK_PRSC_4096` | TWI clock pre-scaler (dividing main processor clock)
| `TWI_CLK_DIV` | `3` | `0` ... `15` | TWI clock divider (dividing twi clock)
| `TWI_DEVICE_ID` | `0x50` | `0x00` ... `0x7F` | First TWI device ID to start. Is incremented until the end of the program is reached, when `TWI_ADDR_BYTES` is `1`.
| `TWI_ADDR_BYTES` | `1` | `1`, `2` | TWI memory address size in number of bytes. When `TWI_ADDR_BYTES` is `1`, `TWI_DEVICE_ID` the gets incremented as well.
|=======================
[IMPORTANT]
Enabling all features while sticking to the minimal RISC-V ISA will result in a too-large binary!
Each configuration parameter is implemented as C-language `define` that can be manually overridden (_redefined_) when
invoking the bootloader's makefile. The according parameter and its new value has to be _appended_
(using `+=`) to the makefile `USER_FLAGS` variable. Make sure to use the `-D` prefix here. The configuration is also listed in the makefile of the bootloader.
For example, to configure a UART Baud rate of 57600 and redirecting the status LED to GPIO output pin 20
use the following command:
.Example: customizing, re-compiling and re-installing the bootloader
[source,console]
----
sw/bootloader$ make USER_FLAGS+=-DUART_BAUD=57600 USER_FLAGS+=-DSTATUS_LED_PIN=20 clean_all bootloader
----
[NOTE]
The `clean_all` target ensure that all libraries are re-compiled. The `bootloader` target will automatically
compile and install the bootloader to the HDL boot ROM (updating `rtl/core/neorv32_bootloader_image.vhd`).
:sectnums:
=== Auto-Boot Configuration
The default bootloader provides a UART-based user interface that allows to upload new executables
at any time. Optionally, the executable can also be programmed to an external SPI flash by the bootloader (see
section <<_programming_an_external_spi_flash_via_the_bootloader>>).
The bootloader also provides an _automatic boot sequence_ (auto-boot) which will start copying an executable
from external SPI flash to IMEM using the default SPI configuration. By this, the default bootloader
provides a "non-volatile program storage" mechanism that automatically boots from external SPI flash
(after `AUTO_BOOT_TIMEOUT`) while still providing the option to re-program the SPI flash at any time
via the UART console.

View file

@ -1,69 +0,0 @@
<<<
:sectnums:
== Programming an External SPI Flash via the Bootloader
The default processor-internal NEORV32 bootloader supports automatic booting from an external SPI flash.
This guide shows how to write an executable to the SPI flash via the bootloader so it can be automatically
fetched and executed after processor reset. For example, you can use a section of the FPGA bitstream configuration
memory to store an application executable.
.Customization
[NOTE]
This section assumes the _default_ configuration of the NEORV32 bootloader.
See section <<_customizing_the_internal_bootloader>> on how to customize the bootloader and its setting
(for example the SPI chip-select port, the SPI clock speed or the **flash base address** for storing the executable).
:sectnums:
=== Programming an Executable
[start=1]
. At first, reset the NEORV32 processor and wait until the bootloader start screen appears in your terminal program.
. Abort the auto boot sequence and start the user console by pressing any key.
. Press u to upload the executable that you want to store to the external flash:
[source]
----
CMD:> u
Awaiting neorv32_exe.bin...
----
[start=4]
. Send the binary in raw binary via your terminal program. When the upload is completed and "OK"
appears, press `s` to trigger the programming of the flash (do not execute the image via the `e`
command as this might corrupt the image):
[source]
----
CMD:> u
Awaiting neorv32_exe.bin... OK
CMD:> s
Write 0x000013FC bytes to SPI flash @ 0x02000000? (y/n)
----
[start=5]
. The bootloader shows the size of the executable and the base address inside the SPI flash where the
executable is going to be stored. A prompt appears: Type `y` to start the programming or type `n` to
abort.
[TIP]
Section <<_customizing_the_internal_bootloader>> show the according C-language `define` that can be modified
to specify the base address of the executable inside the SPI flash.
[source]
----
CMD:> u
Awaiting neorv32_exe.bin... OK
CMD:> s
Write 0x000013FC bytes to SPI flash @ 0x02000000? (y/n) y
Flashing... OK
CMD:>
----
[NOTE]
The bootloader stores the executable in **little-endian** byte-order to the flash.
[start=6]
. If "OK" appears in the terminal line, the programming process was successful. Now you can use the
auto boot sequence to automatically boot your application from the flash at system start-up without
any user interaction.

View file

@ -0,0 +1,80 @@
<<<
:sectnums:
== Using the NEORV32 Bootloader
.Customization
[NOTE]
This section assumes the _default_ configuration of the NEORV32 bootloader.
See the NEORV32 data sheet's bootloader section for more information.
:sectnums:
=== Bootloader SPI Flash Requirements
The bootloader can access an SPI-compatible flash via the processor's top entity SPI port. By default, the flash
chip-select line is driven by `spi_csn_o(0)` and the SPI clock uses 1/8 of the processor's main clock as clock frequency.
The SPI flash has to support single-byte read and write operations, 24-bit addresses and at least the following standard commands:
* `0x02`: Program page (write byte)
* `0x03`: Read data (byte)
* `0x04`: Write disable (for volatile status register)
* `0x05`: Read (first) status register
* `0x06`: Write enable (for volatile status register)
* `0xAB`: Wake-up from sleep mode (optional)
* `0xD8`: Block erase (64kB)
.SPI Flash Power Down Mode
[NOTE]
The bootloader will issue a "wake-up" command prior to using the SPI flash to ensure it is not
in sleep mode / power-down mode (see https://github.com/stnolting/neorv32/pull/552).
:sectnums:
=== Programming an External SPI Flash via the Bootloader
The default processor-internal NEORV32 bootloader supports automatic booting from an external SPI flash.
This guide shows how to write an executable to the SPI flash via the bootloader so it can be automatically
fetched and executed after processor reset. For example, you can use a section of the FPGA bitstream
configuration memory to store an application executable.
[start=1]
. At first, reset the NEORV32 processor and wait until the bootloader start screen appears in your terminal program.
. Abort the auto boot sequence and start the user console by pressing any key.
. Press `u` to upload the executable that you want to store to the external flash:
[source]
----
CMD:> u
Awaiting neorv32_exe.bin...
----
[start=4]
. Send the binary in raw binary via your terminal program. When the upload is completed and "OK"
appears, press `s` to trigger the programming of the flash::
[source]
----
CMD:> u
Awaiting neorv32_exe.bin... OK
CMD:> s
Write 0x00001614 bytes to SPI flash @0x00400000 (y/n)?
----
[start=5]
. The bootloader shows the size of the executable and the base address of the SPI flash where the
executable will be stored. A prompt appears: type `y` to start the programming or type `n` to abort.
[source]
----
CMD:> u
Awaiting neorv32_exe.bin... OK
CMD:> s
Write 0x00001614 bytes to SPI flash @0x00400000 (y/n)?
Flashing... OK
CMD:>
----
[start=6]
. If "OK" appears in the terminal line, the programming process was successful. Now you can use the
auto boot sequence to automatically boot your application from the flash at system start-up without
any user interaction.