Repository navigation
feat(firmware): image identity block and bootloader-ready app layout #362
Copy link
Copy link
Closed
Labels
enhancementNew feature or requestNew feature or requestfirmwareFirmware implementation workFirmware implementation workpriority: mediumWanted and scoped; not blocking todayWanted and scoped; not blocking today
Milestone
Description
Goal
Every STM32 app image carries a small identity block and is laid out to sit behind the bootloader, so the bootloader, the Gateway uploader and the client can all check an image before and after flashing.
Depends on #361 (spike — done).
Plan (signed off 2026-10-25)
- Scope: production firmware only —
Templates/(PanelBridge, PanelGroup),Panels/(Center_Armament, PDU_Left/Right/Center),Examples/(E2E_DCS_Test, and SoakRig once test(firmware): add SoakRig node sketches for the #291 soak rig #339 lands — the test(firmware): v1.0 stability gate — multi-node live-DCS soak + API/wire freeze review #290 soak runs on the bootloader layout).Tests/stay plain ST-Link builds at0x08000000: they only prove the code compiles and are loaded by hand; library-test bench boards carry no bootloader. - Bootloader offset: 4 KB (
0x1000) — the smallest that works: the F103 write-protects in 4 KB blocks, and the bootloader protects its own block, so the app must start at the next one. Today's bootloader is 2.6 KB (test(firmware): CAN bootloader spike — minimal own bootloader, two STM32s then the RP2040 #361). - The offset flips in feat(firmware): CAN bootloader — core #363, with the bootloader and the bootstrap image. feat(firmware): image identity block and bootloader-ready app layout #362 ships the identity block and a shared layout switch left at offset 0, so no board is ever left with nothing at
0x08000000. - Identity block at a fixed
app start + 0x200(0x08000200now,0x08001200after the flip) — the same address on every chip; costs ~244 B of padding after the F103's vector table. - Shared files in
Firmware/shared/:stm32.ini(common settings: the linker script, the stamp step, later the offset — one line),stm32.ld(the STM32 core's linker script + an.osh_identitysection at+0x200),osh_image.py(post-build stamp: flat binary → length + CRC-32/MPEG-2 skipping the CRC word →objcopy --update-sectioninto the.elf; the.binis made from the stamped.elf). Each in-scopeplatformio.inigets two lines pointing at them. FirmwareImagelibrary —FirmwareImage.h: the layout, constants and CRC test vectors (synced to the client for SkyHawkClient#177). The instance is defined in each role library with its kind — PanelGroup, PduNode, PanelBridge — plus a weak fallback in STM32Board (kind UNKNOWN).- Verify first on one project, before the sweep: the custom linker script still gets the core's offset / size settings, the stamp runs before the
.bin, the stamped.elfflashes over ST-Link, the PDU's size limit still holds.
Identity block (32 bytes, little-endian, fixed offset after the vector table, e.g. app start + 0x200)
| Offset | Size | Field | Source |
|---|---|---|---|
| 0 | 4 | magic = "OSKY" |
constant |
| 4 | 2 | layoutVersion |
constant, starts at 1 |
| 6 | 2 | blockSize (= 32) |
constant — readers parse the prefix they know (#295 growth rule) |
| 8 | 4 | imageLength |
post-build stamp |
| 12 | 4 | imageCrc — CRC-32/MPEG-2 over the image, this field excluded |
post-build stamp |
| 16 | 1 | nodeId |
the same NODE_ID macro the code uses (D10) |
| 17 | 1 | nodeKind |
CANProtocol's kind constant (#344) |
| 18 | 3 | fwMajor / fwMinor / fwPatch |
FirmwareVersion.h (#295 A11) — the same value READY reports |
| 21 | 11 | reserved, 0 | — |
No commit id and no "dev build" flag: release images are built from the release tag, so the version identifies the commit; dev builds keep the last release's version (accepted).
Scope
- The block as a
conststruct in a shared header, placed by a linker section at the fixed offset (project copy of the core's linker script, or a core option — to verify). - App start at the bootloader offset in a shared PlatformIO config:
board_upload.offset_address+-DVECT_TAB_OFFSET. - Post-build step fills
imageLength+imageCrcin both.binand.elf(objcopy --update-section) — ST-Link uploads flash the.elf, and an unstamped app would fail the bootloader's boot check. - CRC-32/MPEG-2 = the F103 hardware CRC unit's algorithm (≠ zip CRC-32 / Node
zlib.crc32). Export test vectors for the client vianpm run sync. - Spec + docs in the same PR (FirmwarePlan, TechSpec,
docs/firmware/).
From the spike (#361)
- App offset — settled.
board_build.flash_offset = 0x2000+board_upload.offset_address = 0x08002000. The STM32 core turnsflash_offsetintoVECT_TAB_OFFSET(itsSystemInitsetsVTOR) and the linker'sLD_FLASH_OFFSET, so no project copy of the linker script is needed for the offset. Verified on the bench: the app reportsVTOR = 0x08002000. (The identity block's fixed spot may still need one linker section.) - Offset = 8 KB for now — the bootloader is 2.2–2.6 KB, so 4 KB fits too; pick once feat(firmware): CAN bootloader — safety features #364's features are measured.
board_upload.maximum_size= 64 KB − the bootloader, so an app that outgrows its space fails the build.- CRC-32/MPEG-2 (the F103's hardware unit, 32-bit little-endian words) matched a host implementation on every bench run — use that algorithm and those test vectors.
- Spike code: local branch
spike/361-bootloader(370fcf12, 24c949ec — not pushed),Firmware/Spike/Bootloader361/app/.
Done when
Every STM32 project builds with the block; a host test checks the stamped CRC against the test vectors; ST-Link flashing of a stamped .elf still boots.
Client side
OpenSkyHawk/SkyHawkClient#177 (From file… reads the identity block) — design: https://claude.ai/artifact/R8DXWWC4uyAby54tBQLo8v (Cockpit board).
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or requestfirmwareFirmware implementation workFirmware implementation workpriority: mediumWanted and scoped; not blocking todayWanted and scoped; not blocking today
Activity
fix(firmware): close files the image stamp reads (#362)
feat(firmware): image identity block on every production STM32 image (#…
test(firmware): put SoakRig on the bootloader layout, -flto on board B
feat(update): uploader client and firmware image identity sync (#187 …