Files
templates/c/set-protocol/ports/stm32f407-usb-boot

STM32F407VET6 USB boot port

SET v2 single-slot updater: include/set_boot.h, src/set_boot.c and the existing set_firmware codec. Byte transport is supplied by the application, independently of the Flash callbacks. The emulator project supplies the ST USB CDC stream.

Integration in another F407 project

  1. Copy boot_config.template.h to the project's include directory as boot_config.h: set crystal frequency, SET node and product model. Match the crystal frequency with HAL HSE_VALUE.
  2. Compile src/set_protocol.c, src/set_firmware.c, src/set_boot.c and this port's boot_main.c, boot_flash.c, boot_request.c, boot_usb_stream.c.
  3. Provide STM32F4 CMSIS/HAL, startup, the ST USB device CDC middleware and the board USB transport (usb_cdc.h, usb_setp_stream.h and their implementation). The transport calls usb_setp_feed/usb_setp_reset from this port instead of an application command dispatcher. Enable SET v2 for the bootloader build.
  4. Link boot code below 0x0800C000; link the application at 0x08010000. Add boot_request.c to the application and periodically call f407_reset_poll; its update command calls f407_request_boot.

The emulator's Bootloader/Src/*.c files are include-only build wrappers. Neither the portable updater nor this port depends on the emulator models or its board_config.h. The USB transport and HAL configuration remain board supplied.

Flash layout (512 KiB device): boot sectors 0..2 at 0x08000000 (48 KiB), commit record in sector 3 at 0x0800C000, application sectors 4..7 at 0x08010000 (448 KiB). All addresses and sector operations are in this port. The sector programming/jump approach is adapted from climate's climate_control_f407vet6_f4/Bootloader/bootloader_f407.c.

BEGIN requires slot 0, base 0x08010000, size 8..458752, block size 1..256, ERASE_SLOT flag only, zero SHA/key/signature. DATA must be sequential; its CRC, length and bounds are checked. END requires complete receipt and matching size and CRC. The port verifies the actual Flash CRC and vector table before writing the commit marker last. SHA, signatures, automatic activation and resume are not supported and are rejected explicitly. CRC is an integrity check.

STATUS returns the standard 16-byte SET firmware status. ACTIVATE accepts an empty payload after END; the transport adapter defers reset to let the USB reply finish. ABORT clears the RAM session; it does not restore erased firmware. On reset, SP and reset PC are checked like in climate. USB metadata is not required, so Keil/SWD installs and alternating SWD/USB updates work even with absent or stale USB metadata. Preserve the bootloader using sector erase rather than full-chip erase. Reflash the updated bootloader once to adopt this behavior. USB END/ACTIVATE still require complete receipt and CRC verification.

Like climate, the reset vector check cannot detect incomplete images once valid vectors are written: after an interrupted update and reset such an image may run. To recover an unresponsive app, erase sector 4 at 0x08010000 via SWD, reset, and upload the full image again. Erasing metadata sector 3 no longer forces bootloader entry. An interrupted update requires a fresh BEGIN and full retransmission. test_boot_image.c is a host-only regression test; do not add it to firmware targets.

boot_request.c is shared by the application and bootloader. Product command 0x1003 (empty payload) in the application sets RTC backup register 0 and schedules reset after 500 ms. The bootloader consumes that flag before deciding whether to jump. Reserve BKP0R for this port. The jump must run early after reset, before enabling peripheral interrupts, USB or DMA. Both images must set VTOR to their own link address in SystemInit.

Board: PA11 D-/PA12 D+, existing self-powered OTG_FS CDC port, 25 MHz HSE; no VBUS host drive, PA9/PA10 are not used. Flash erase uses x32 at nominal 3.3 V, programming uses bytes to support unaligned protocol blocks. Hardware acceptance must cover disconnect/power loss during erase, programming and commit.

The SET USB command dispatcher is shared with G474 in ../stm32-usb-boot/boot_usb_protocol.inc; keep that directory when importing this port.