STM32H755 stalling CPU when erasing bank 1 flash from code running in bank 2 (but not the other way around)
I am implementing a firmware-update mechanism on STM32H755 (Nucleo board, MCU rev U) in which the two flash banks are independent. New firmware is flashed by erasing the "other" bank (which is always mapped at 0x0810 0000 and accessed with the ____2 register set, e.g. FLASH_CR2), then writing the candidate firmware image into that bank, verifying a SHA hash after programming, and finally toggling the SWAP_BANK bit in option bytes, performing an option-byte update, and software reset to boot into the new image. This works, and I can perform one update after another, ping-ponging back and forth between the banks. Note that the running application is always mapped at 0x0800 0000, is [much] less than 1 MByte, and never touches the other bank at 0x0810 0000 except to erase and program it when an update is requested.
The issue I am having is that when the code runs in Bank 2 and an update commences, the bank erase of Bank 1 is stalling the CPU for several seconds. The same thing does *not* happen when the code is running in Bank 1 and performs a bank erase on Bank 2. Also, the actual programming never stalls the CPU---only the initial bank erase, and only when it is Bank 1 being erased.
AFAICT, there is no difference at all between these two scenarios---everything should be identical between them, down to the contents of every single register and memory location, *except* for the SWAP_BANK bit in the option bytes. So why would one behave differently? (Note, for this test, I am updating with an identical firmware image, so there is no difference pre- and post-update.)
I was able to find corroborating evidence of this unexpected behavior in another forum post, here:
(Note the OP is not describing it---it's later in the thread, user
I know better than to claim a silicon bug :) although I cannot think of another explanation. Can you? Best-case scenario, someone has figured out an undocumented way around this problem.
Why does this matter? Well, I'd like to use a watchdog timer, and 4+ seconds is a pretty long watchdog expiration. Also, other RTOS tasks are supposed to be running in the background during the update process, and they do, just fine---when the code is running in Bank 1.
