Empty check mechanism on STM32
STM32 MCUs feature the system memory boot mode, which enables programming the device through the integrated peripheral interfaces, as outlined in AN2606 - Introduction to system memory boot mode on STM32 MCUs
To select system memory boot mode at device startup, a pattern as outlined in AN2606 must be applied. This typically involves configuration of the option bytes or applying voltages to certain MCU pins.
On some STM32 devices, their respective bootloader activation pattern contains a specific provision for entering the system memory boot mode: the empty check mechanism. On power-on reset, the MCU checks the value at the first address of the flash memory, and enters system memory boot mode if this value is unprogrammed (equal to 0xFFFFFFFF). These are devices to which bootloader activation patterns 6, 11, 13 and 16 from AN2606 apply.
STM32 MCUs featuring the empty check mechanism
The following MCUs feature bootloader activation patterns 6, 11, 13, 16 as per AN2606:
| STM32 Series | STM32 MCU |
| F0 |
|
| C0 |
|
| G0 |
|
| L0 |
|
| L4 |
|
| U0 |
|
| WL |
|
| WB |
|
Issues
The empty check only being present on select devices may result in unexpected behavior for users. On previously unprogrammed MCUs featuring the empty check mechanism, system memory boot mode is entered automatically upon power-on reset until they are programmed. The following issues may arise from this:
- Certain GPIO pins are reconfigured from analog mode after reset to enable the communication periphery - some may be pulled high or low, potentially damaging connected components. - see Bypassing the empty check mechanism for a solution to this issue.
- After programming is complete, user code is not executed upon reset, with the MCU entering the integrated bootloader instead - see Clearing the empty check bit.
- The fact that the bootloader was entered may lead the user to believe that they correctly achieved one of the conditions for the bootloader's activation pattern as described in AN2606, whereas the MCU entered the integrated bootloader solely due to the empty check mechanism. In this case, upon programming the MCU, an unsuspecting user may not be able to enter the integrated bootloader again without the use of a debugger, for example due to option byte configuration - see Ensuring access to system memory boot mode regardless of the empty check mechanism.
Bypassing the empty check mechanism
To prevent a previously unprogrammed MCU from entering system memory boot mode upon startup:
- Keep the nRST signal low to keep the device under reset.
- Use a debugger to connect to the MCU Under reset. The MCU is stopped before executing any instructions, so the GPIO is kept unconfigured.
- Program the application in the FLASH.
- Clear the Empty check bit to boot from flash on next reset - see Clearing the empty check bit.
Clearing the empty check bit
STM32 MCUs do not automatically clear the "flash empty" bit after the flash has been programmed through system memory boot mode. This means that subsequent resets will result in the MCU again entering the integrated bootloader, as the flash is still considered "empty". In order to rectify this:
- The empty check bit is cleared by the MCU on power-on reset (e.g. a power cycle), or by reloading the option bytes (see OBL_LAUNCH in reference manuals).
- On STM32G0 and STM32WB it is possible to clear the empty check flag by resetting the FLASH_ACR.EMPTY bit.
- The system bootloader on STM32F04x and STM32F070x6 can detect that flash is no longer empty. It then changes the boot memory mapping to Main Flash and performs a jump to user code programmed there.
Ensuring access to system memory boot mode regardless of the empty check mechanism
In this specific case, on the MCUs requiring Pattern 11 for bootloader activation, as per AN2606, the factory default setting of option bits provides no mechanism to enter the bootloader by applying voltages to MCU pins. This means that after the initial programming of flash, the bootloader cannot be entered unless explicitly done so in user code by either jumping to the bootloader code or modifying the option bytes and performing a reset.
If the application has no other provision for entering the integrated bootloader, and it is required to be used in place of a debugger, it will be necessary to program the nBOOT0_SEL bit of a fresh MCU to "0" in order for the MCU to select between user code and the integrated bootloader based on the voltage applied to the BOOT0 pin.
Due to the empty check bit not being cleared automatically when flash is programmed (see Clearing the empty check bit), the user may erroneously assume that their option byte configuration allows them to enter system memory boot mode upon reset, whereas this may not be the case, and the MCU has simply re-entered the integrated bootloader due to the empty check bit still being set. Afterwards, when a power-cycle is performed and the empty check bit is cleared, the integrated bootloader can not be accessed anymore. Care must be taken to ensure the correct configuration of option bytes for these MCUs if re-entering system memory boot mode is necessary during development (double-check the option byte configuration when programming the MCU).
See also: “STM32 boot and startup tips" MOOC
