Mohamed Salem 4f1199a3e6 Scaffold bootloader project with TODO checklist
New project under bootloader/ with the same structure as
color_switcher: Dockerfile, docker-compose, modular CMake, and
APP_BOOT + SYS_ECU stub components. Reuses common/ submodules for
MCU_UART, MCU_USB, HAL_COM, STD_TYPES.

TODO.md lists all open design decisions (interface, protocol, flash
layout, entry trigger, integrity checks, flash strategy) and the
implementation tasks that depend on them.
2026-04-18 23:37:33 +02:00

61 lines
3.0 KiB
Markdown

# Bootloader — Design Decisions & TODO
## Open Design Decisions
These must be resolved before implementation begins:
### 1. Firmware update interface
- [ ] UART only
- [ ] USB-CDC only
- [ ] Both (selectable via config or auto-detect)
- **Notes:** We have MCU_UART and MCU_USB in common/ ready to use via HAL_COM.
### 2. Transfer protocol
- [ ] Custom simple protocol (length + CRC32 + raw binary)
- [ ] XMODEM / YMODEM (standard, many terminal tools support it)
- [ ] Custom framed protocol (start byte, length, payload, CRC, end byte)
- **Notes:** Custom is simplest to implement. XMODEM is widely supported by serial tools.
### 3. Flash memory layout
- [ ] Define bootloader size (e.g., first 16 KB, 32 KB, or 64 KB of flash)
- [ ] Define application start address
- [ ] Define metadata region (app version, CRC, valid flag)
- **Notes:** RP2040 has 2 MB flash. Pico SDK linker script needs modification to place the bootloader and app at different addresses.
### 4. Bootloader entry trigger
- [ ] Always enter bootloader, wait N seconds for firmware, then jump to app
- [ ] Check a GPIO pin (button held = stay in bootloader)
- [ ] Check a magic value in flash/RAM (set by the application to request update)
- [ ] Combination: check button first, then magic value, then jump to app
- **Notes:** "Button + timeout" is the most user-friendly approach.
### 5. Application jump mechanism
- [ ] Read the app's vector table at the app start address
- [ ] Set the MSP (main stack pointer) from the vector table
- [ ] Jump to the reset handler from the vector table
- **Notes:** Standard Cortex-M0+ boot sequence. Need to disable interrupts and peripherals before jumping.
### 6. Integrity verification
- [ ] CRC32 check on the received firmware before writing to flash
- [ ] CRC32 check on the stored application before jumping (boot-time validation)
- [ ] Signature verification (stretch goal — not needed for initial version)
### 7. Flash write strategy
- [ ] Erase + write as chunks arrive (streaming)
- [ ] Buffer entire firmware in RAM, then erase + write at once (limited by RAM size)
- [ ] Dual-bank: write to alternate region, swap on success (A/B update)
- **Notes:** Streaming is most memory-efficient. A/B is safest (rollback on failure) but uses 2x flash.
## Implementation Tasks
Once design decisions are made:
- [ ] Create linker scripts (bootloader.ld, application.ld) with correct flash regions
- [ ] Implement APP_BOOT_enuInit — check entry trigger, decide boot vs update mode
- [ ] Implement firmware receive via HAL_COM (protocol parsing, CRC validation)
- [ ] Implement flash write using Pico SDK hardware_flash API
- [ ] Implement application jump (disable interrupts, set MSP, branch to reset handler)
- [ ] Implement boot-time app validation (CRC check before jumping)
- [ ] Modify color_switcher's linker script to start at the app address (not 0x10000000)
- [ ] Test: flash bootloader, then send color_switcher firmware over UART/USB
- [ ] Test: corrupt firmware scenario — bootloader should stay in update mode