2026-05-20 2:09 AM
STM32H563ZIT6, single binary (no separate bootloader), dual-bank OTA
Bank1: Current running firmware (original)Bank2: New OTA firmware (potentially corrupted)IWDG: Started in Bank1 before swapOTABootSafetyCheck: In Reset_Handler of every binary buildBKP0R: Boot counter set before swap
After bank swap, if Bank2 firmware is corrupted and Reset_Handler never executes:
Bank swap → resetCPU reads 0x08000000 → SP (may be valid)CPU reads 0x08000004 → Reset vector (may be valid)CPU jumps to Reset_Handler addressReset_Handler code is corrupted → garbage instructions → crashOTABootSafetyCheck never runsBoot counter never incrementsIWDG fires → reset → same crash → infinite loopRollback never happensBank1 original firmware never recoversDevice is permanently stuck
1. OTABootSafetyCheck in Reset_Handler
Reset_Handler: ldr r0, =_estack mov sp, r0 bl OTABootSafetyCheck ; before SystemInit and main bl SystemInit bl __libc_init_array bl main
Works when Reset_Handler body executes. Does not help when Reset_Handler code itself is corrupted.
2. IWDG Started in Bank1 IWDG survives bank swap reset. Bank2 must feed it. If Bank2 never feeds IWDG → reset. But reset always goes back to corrupted Bank2 → same crash → infinite loop.
3. Pre-swap Vector Table Check
uint32_t sp = *(uint32_t *)0x08100000; uint32_t reset = *(uint32_t *)0x08100004;
Catches completely empty or garbage vector table. Does not catch valid vector table pointing to corrupted Reset_Handler body.
Without a separate bootloader, is there any STM32H563 hardware mechanism that can force a bank reswap when:
Specifically: