Merge pull request #3614 from thermigo/main
docs: improve bootloader documentation
This commit is contained in:
commit
7a56e2f9c9
@ -385,3 +385,49 @@ async fn idle() {
|
||||
loop { embassy_futures::yield_now().await; }
|
||||
}
|
||||
----
|
||||
|
||||
== Why is my bootloader restarting in loop?
|
||||
|
||||
== Troubleshooting Bootloader Restart Loops
|
||||
|
||||
If your bootloader restarts in a loop, there could be multiple reasons. Here are some things to check:
|
||||
|
||||
=== Validate the `memory.x` File
|
||||
The bootloader performs critical checks when creating partitions using the addresses defined in `memory.x`. Ensure the following assertions hold true:
|
||||
|
||||
[source,rust]
|
||||
----
|
||||
const {
|
||||
core::assert!(Self::PAGE_SIZE % ACTIVE::WRITE_SIZE as u32 == 0);
|
||||
core::assert!(Self::PAGE_SIZE % ACTIVE::ERASE_SIZE as u32 == 0);
|
||||
core::assert!(Self::PAGE_SIZE % DFU::WRITE_SIZE as u32 == 0);
|
||||
core::assert!(Self::PAGE_SIZE % DFU::ERASE_SIZE as u32 == 0);
|
||||
}
|
||||
|
||||
// Ensure enough progress pages to store copy progress
|
||||
assert_eq!(0, Self::PAGE_SIZE % aligned_buf.len() as u32);
|
||||
assert!(aligned_buf.len() >= STATE::WRITE_SIZE);
|
||||
assert_eq!(0, aligned_buf.len() % ACTIVE::WRITE_SIZE);
|
||||
assert_eq!(0, aligned_buf.len() % DFU::WRITE_SIZE);
|
||||
----
|
||||
|
||||
If any of these assertions fail, the bootloader will likely restart in a loop. This failure might not log any messages (e.g., when using `defmt`). Confirm that your `memory.x` file and flash memory align with these requirements.
|
||||
|
||||
=== Handling Panic Logging
|
||||
Some panic errors might log messages, but certain microcontrollers reset before the message is fully printed. To ensure panic messages are logged, add a delay using no-operation (NOP) instructions before the reset:
|
||||
|
||||
[source,rust]
|
||||
----
|
||||
#[panic_handler]
|
||||
fn panic(_info: &core::panic::PanicInfo) -> ! {
|
||||
for _ in 0..10_000_000 {
|
||||
cortex_m::asm::nop();
|
||||
}
|
||||
cortex_m::asm::udf();
|
||||
}
|
||||
----
|
||||
|
||||
=== Feed the watchdog
|
||||
|
||||
|
||||
Some `embassy-boot` implementations (like `embassy-boot-nrf` and `embassy-boot-rp`) rely on a watchdog timer to detect application failure. The bootloader will restart if your application code does not properly feed the watchdog timer. Make sure to feed it correctly.
|
||||
|
||||
@ -6,6 +6,25 @@ An adaptation of `embassy-boot` for nRF.
|
||||
|
||||
## Features
|
||||
|
||||
* Load applications with or without the softdevice.
|
||||
* Configure bootloader partitions based on linker script.
|
||||
* Using watchdog timer to detect application failure.
|
||||
- Load applications with or without the softdevice.
|
||||
- Configure bootloader partitions based on linker script.
|
||||
- Using watchdog timer to detect application failure.
|
||||
|
||||
## Working with a SoftDevice
|
||||
|
||||
When a SoftDevice is present, it handles starting the bootloader and the application as needed.
|
||||
|
||||
The SoftDevice architecture supports the bootloader via a configurable base address, referred to as `BOOTLOADERADDR`, in the application flash region. This address can be specified either:
|
||||
|
||||
1. At the `MBR_BOOTLOADER_ADDR` location in flash memory (defined in `nrf_mbr.h`), or
|
||||
2. In the `UICR.NRFFW[0]` register.
|
||||
|
||||
The `UICR.NRFFW[0]` register is used only if `MBR_BOOTLOADER_ADDR` has its default value of `0xFFFFFFFF`. This bootloader relies on the latter approach.
|
||||
|
||||
In the `memory.x` linker script, there is a section `.uicr_bootloader_start_address` (origin `0x10001014`, length `0x4`) that stores the `BOOTLOADERADDR` value.
|
||||
Ensure that `__bootloader_start` is set to the origin address of the bootloader partition.
|
||||
|
||||
When a bootloader is present, the SoftDevice forwards interrupts to it and executes the bootloader reset handler, defined in the bootloader's vector table at `BOOTLOADERADDR`.
|
||||
|
||||
Once the bootloader loads the application, the SoftDevice initiates the Application Reset Handler, defined in the application’s vector table at APP_CODE_BASE hardcoded in the SoftDevice.
|
||||
The active partition's origin **must** match the `APP_CODE_BASE` value hardcoded within the SoftDevice. This value can be found in the release notes for each SoftDevice version.
|
||||
|
||||
@ -1,11 +1,37 @@
|
||||
# Bootloader for STM32
|
||||
|
||||
The bootloader uses `embassy-boot` to interact with the flash.
|
||||
This bootloader implementation uses `embassy-boot` and `embassy-usb-dfu` to manage firmware updates and interact with the flash memory on STM32WB55 devices.
|
||||
|
||||
# Usage
|
||||
## Prerequisites
|
||||
|
||||
Flash the bootloader
|
||||
- Rust toolchain with `cargo` installed
|
||||
- `cargo-flash` for flashing the bootloader
|
||||
- `dfu-util` for firmware updates
|
||||
- `cargo-binutils` for binary generation
|
||||
|
||||
## Usage
|
||||
|
||||
### 1. Flash the Bootloader
|
||||
|
||||
First, flash the bootloader to your device:
|
||||
|
||||
```
|
||||
cargo flash --features embassy-stm32/stm32wb55rg --release --chip STM32WB55RGVx
|
||||
```
|
||||
|
||||
### 2. Build and Flash Application
|
||||
|
||||
Generate your application binary and flash it using DFU:
|
||||
|
||||
```
|
||||
cargo objcopy --release -- -O binary fw.bin
|
||||
dfu-util -d c0de:cafe -w -D fw.bin
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- Make sure your device is in DFU mode before flashing
|
||||
- Verify the USB VID:PID matches your device (c0de:cafe)
|
||||
- Check USB connections if the device is not detected
|
||||
- Make sure the transfer size option of `dfu-util` matches the bootloader configuration. By default, `dfu-util` will use the transfer size reported by the device, but you can override it with the `-t` option if needed.
|
||||
- Make sure `control_buf` size is larger than or equal to the `usb_dfu` `BLOCK_SIZE` parameter (in this example, both are set to 4096 bytes).
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user