stm32u5: fix erase bank selection when SWAP_BANK is active#821
Merged
mattia-moffa merged 3 commits intoJul 9, 2026
Merged
Conversation
On STM32U5 the BKER bit in FLASH_NSCR/SECCR always selects the physical bank: the SWAP_BANK option only changes the address mapping of the banks (RM0456 7.5.8, and confirmed on silicon). hal_flash_erase derived BKER from the logical address only, so with SWAP_BANK active every page erase landed in the bank opposite to the one mapped at the target address. In DUALBANK_SWAP mode this broke fallback recovery: when image verification failed while running from bank 2, wolfBoot_erase_partition (PART_UPDATE) erased the healthy image in the active bank instead of the failing update, leaving the device unable to boot. The same mismatch corrupted any erase issued while swapped, including staging a new update from the application. Invert BKER when both DBANK and SWAP_BANK are set, mirroring the STM32H5 HAL which already handles this (RM0481 has the same physical bank semantics). STM32L5 is not affected: RM0438 defines NSBKER as the page number MSB, which follows the mapped address. Verified on the m33mu emulator with hardware-faithful BKER/SWAP_BANK modeling: full cycle (update to bank 2, swap, stage corrupt update, verify failure) now erases the corrupt update and falls back to the healthy image; before this fix the healthy image was erased and the device bricked.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes STM32U5 flash page erase bank selection when SWAP_BANK is enabled in dual-bank mode, ensuring the BKER bit targets the correct physical bank under swapped address mapping. This prevents erroneous erases during swapped execution scenarios (e.g., fallback recovery after a failed update verification).
Changes:
- Adjust
hal_flash_erase()to invert the computedBKERselection when bothDBANKandSWAP_BANKare set. - Add an in-code comment documenting the STM32U5 BKER/SWAP_BANK behavior and rationale for the inversion.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Add a GitHub Actions workflow covering the DUALBANK_SWAP fallback
scenario fixed by the previous commit, running on the m33mu emulator
(wolfboot-ci-m33mu image, which models the physical-bank BKER/SWAP_BANK
semantics of the STM32U5 flash controller).
The test drives three boots in a single emulator session with the
stm32u5-nonsecure-dualbank config:
1. wolfBoot verifies a valid v2 image in the UPDATE partition,
activates SWAP_BANK and reboots;
2. the v2 app, now running from physical bank 2, stages a fake v3
image with a broken integrity record into the logical UPDATE
partition and reboots;
3. wolfBoot selects the v3 update, fails verification, and must erase
the corrupt update and fall back to v2, which reports success via
breakpoint.
Besides the success breakpoint, the script checks the emulator flash
trace: the UPDATE partition must be erased and the BOOT partition
(holding the healthy image) must never be touched, so a regression
cannot hide behind an accidentally bootable state. Verified to fail
against the pre-fix hal_flash_erase, where boot 3 erases the healthy
image and the device bricks.
The top-level Makefile defaults WOLFBOOT_ROOT to $(PWD), which is the environment value of the invoking step: under the workflow's working-directory (test-app/emu-test-apps) the keytools paths resolved under the wrong root and keygen was never found, so src/keystore.c was missing and the wolfboot build failed. Export the computed absolute WOLFBOOT_ROOT so the make invocations resolve tool paths correctly wherever the script is started from.
mattia-moffa
approved these changes
Jul 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
zd22118
On STM32U5 the BKER bit in FLASH_NSCR/SECCR always selects the physical bank: the SWAP_BANK option only changes the address mapping of the banks (RM0456 7.5.8, and confirmed on silicon). hal_flash_erase derived BKER from the logical address only, so with SWAP_BANK active every page erase landed in the bank opposite to the one mapped at the target address.
In DUALBANK_SWAP mode this broke fallback recovery: when image verification failed while running from bank 2, wolfBoot_erase_partition (PART_UPDATE) erased the healthy image in the active bank instead of the failing update, leaving the device unable to boot. The same mismatch corrupted any erase issued while swapped, including staging a new update from the application.
Invert BKER when both DBANK and SWAP_BANK are set, mirroring the STM32H5 HAL which already handles this (RM0481 has the same physical bank semantics). STM32L5 is not affected: RM0438 defines NSBKER as the page number MSB, which follows the mapped address.
Verified on the m33mu emulator with hardware-faithful BKER/SWAP_BANK modeling: full cycle (update to bank 2, swap, stage corrupt update, verify failure) now erases the corrupt update and falls back to the healthy image; before this fix the healthy image was erased and the device bricked.