Custom Bootloader via CAN - #22
rickydamaraju wants to merge 5 commits into
Conversation
There was a problem hiding this comment.
I found several issues that should be addressed before this is used on the vehicle:
-
Boot handoff leaves SysTick active.
jump_to_application()callsHAL_DeInit(), but this HAL implementation does not disable SysTick. It then changes VTOR/MSP and re-enables interrupts before entering the application reset handler. A pending tick can execute application interrupt code before.dataand.bssinitialization. Disable SysTick and clear pending/enabled NVIC state before changing the stack and branching. -
The temperature application now interrupts on every CAN frame.
CAN_Init_Filter()still uses an all-zero ID/mask, while this branch enables the FIFO0 pending interrupt. Every frame on a busy vehicle bus will invoke the ISR just to discard it. Configure a filter for standard ID0x600 + nodeinstead. -
Every normal build silently uses node 1. Both
BL_NODE_IDandBOOTLOADER_NODE_IDdefault to 1, and neither build exposes a documented node parameter. Multiple boards will reset together and can produce colliding bootloader responses. Make the node explicit in both builds and fail compilation when it is omitted. -
The application vector relocation edit is inactive.
VECT_TAB_OFFSETis0x4000, butUSER_VECT_TAB_ADDRESSremains undefined. Bootloader handoff sets VTOR, but direct debug/application startup will use the bootloader vector table. Enable the relocation in the application build. -
The host receive-queue drain can run forever.
enter_bootloader()loops until nonblockingrecv()returnsNone; a saturated bus can keep that loop alive indefinitely. Bound the drain or set a receive filter for the selected response ID. -
Response parsing needs validation.
_response()unpacks any matching arbitration ID as exactly eight bytes and does not verify the returned command. A malformed or delayed response can abort or satisfy the wrong operation. Validate standard/data frame type, DLC, and expected command.
Also, CRC provides corruption detection but not firmware authenticity. If the CAN bus is not explicitly treated as trusted, any participant can erase and replace the application, so the update protocol needs authentication or signature verification (low prio).
| /* Change per PCB (valid range: 1..7). */ | ||
| #ifndef BL_NODE_ID | ||
| #define BL_NODE_ID 1U | ||
| #endif |
There was a problem hiding this comment.
in main.c you use BOOTLOADER_NODE_ID and here it is BL_NODE_ID - are these supposed to be the same?
|
The bootloader handoff, CAN filtering, vector relocation, and node-ID configuration were fixed to make updates safer and prevent multiple boards from responding incorrectly. The flashing tool now limits queue draining and validates every response’s CAN frame type, length, and command before accepting it. Both oscillator versions compile successfully, all tests pass, and firmware authentication is documented as a future improvement. |
jeevanshah07
left a comment
There was a problem hiding this comment.
Review written by GPT-6 Astra on behalf of Jeevan, based on the supplied review findings.
The shared vector-table relocation prevents reliable bootloader operation. The update completion handshake and application node-selection builds also contain functional defects that should be fixed before merging.
-
[P1] Keep the bootloader vector table at its own flash origin —
rfr26-tempSensor/Core/Src/system_stm32f1xx.c:110The bootloader Makefile also compiles this
system_stm32f1xx.c, so itsSystemInit()now sets VTOR to the application at0x08004000. OnceHAL_Init()enables SysTick, interrupts use application vectors instead of the bootloader's handlers; on a freshly installed board these vectors are erased, causing a fault before flashing can work. Make the offset build-specific so the bootloader uses zero and only the application uses0x4000. -
[P2] Wait for START after completing an update —
stm32f103-can-bootloader/src/main.c:140-142When an update takes longer than the 1.5-second startup window, END sets
rx_statetoRX_IDLEand the same main-loop iteration jumps into the application before processing another frame. However,can_flash.pyalways sends START after receiving COMPLETE and waits for its acknowledgement. The application does not handle START, so a successful update ends with a host timeout. Keep completed updates in a state that awaits START, or explicitly align the host protocol with automatic startup. -
[P2] Rebuild application objects when NODE changes —
rfr26-tempSensor/Debug/Core/Src/subdir.mk:31Building with
NODE=1and thenNODE=2reuses the same application objects because make does not track changes to command-line compiler definitions. The second binary therefore still listens for node 1's reset command, despite being built for node 2, preventing correctly addressed updates and potentially resetting another board. Track NODE as a build dependency or use per-node output directories, as the bootloader already does; apply this to both Debug and Release.
|
The bootloader now keeps its vector table at its own flash origin, while application builds relocate theirs to 0x08004000. After completing an update, the bootloader waits for and acknowledges the host’s START command before launching the application. Debug and Release builds now recompile the node-dependent code every time, preventing stale node IDs. |
…-bootloader # Conflicts: # .gitignore
Addresses ticket #19. Adds a CAN 2.0 bootloader for the STM32F103T8U6, supporting board-specific firmware transfer, flash erase, CRC verification, retries, application startup, and remote reset. It also includes a Python flashing tool, automated tests, and the memory-layout changes required for the temperature-board application.