cancel
Showing results for 
Search instead for 
Did you mean: 

Empty check mechanism on STM32

Martin HUBIK
Associate III

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
  • STM32F04xxx
  • STM32F070x6
  • STM32F09xxx
C0
  • STM32C011xx
  • STM32C031xx
  • STM32C051xx
  • STM32C071xx
  • STM32C091xx/92xx
G0
  • STM32G03xxx/STM32G04xxx
  • STM32G05xxx/061xx
  • STM32G07xxx/08xxx
  • STM32G0B0xx
  • STM32G0B1xx/0C1xx
L0
  • STM32L01xxx/02xxx
L4
  • STM32L412xx/422xx
  • STM32L43xxx/44xxx
  • STM32L45xxx/46xxx
  • STM32L496xx/4A6xx
  • STM32L4Rxxx/4Sxxx
U0
  • STM32U031xx
  • STM32U073xx/83xx
WL
  • STM32WLE5xx/55xx
WB
  • STM32WB10xx/15xx
  • STM32WB30xx/35xx/50xx/55xx

 

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

Comments
TDK
Super User

(edit: thanks for fixing typo)

waclawek.jan
Super User

Let's try invoke the author, maybe he will fix it @Martin HUBIK​ 

TDK
Super User

@Martin HUBIK Any chance this could be updated for the recent additions? In particular the U5, H5 and C0 series, but I think there are others.

waclawek.jan
Super User

There's an additional mechanism in STM32 which are not in the list above and which indeed don't primarily check FLASH to be empty, but have dual-bank FLASH, e.g. 'G4 - if the BLB2 option bit is set (i.e. boot from bank 2 selected, and this is NOT the default setting) and all other bits and pins are set to boot from user FLASH, the bootloader is still entered if neither FLASH contains valid code.

In the 'G4 RM0440, this fact is not contained in the Boot modes table, but is somewhat hidden in the following narrative, so it's relatively easy to miss.

BKara.3
Associate II

Hello everyone,

We recently discovered the "Empty Check Mechanism" on the STM32U0 series of MCUs - specifically the STM32U083CC - and wanted to share our experience in case it helps others encountering similar issues in the future.

Our device is designed to be battery-powered and deployed in remote (often unattended) locations. As such, implementing a power-on cycle reset feature was essential, in addition to managing various sensors and actuators. This reset is triggered by either a GPIO signal or an external monitoring circuit that cuts power and restores it after a short delay.

We chose the STM32U0 series for its low power consumption, which made it a suitable candidate for our application.

During the design phase, we reviewed all available documentation for the STM32U0 family, but skipped AN2606, assuming it was only relevant to the internal bootloader - which we didn’t plan to use. Unfortunately, we were unaware of the Empty Check Mechanism, and we had connected the GPIO used for triggering the external power-on cycle to one of the bootloader-related GPIOs.

We acknowledge that this issue could have been avoided had we thoroughly reviewed all documentation. However, we relied on our experience from previous projects using other STM32 families, where this mechanism did not exist, and we were accustomed to the traditional handling of the BOOT0 pin.

As we’re using a debug setup via SWDIO/SWDCLK (J-Link/ST-Link), this led to an unexpected issue: we were unable to program the device initially as we normally would.

Thankfully, we caught this during the first prototype stage and will be reassigning the affected pins in the production version. However, we struggle to see the reasoning behind this behavior. The traditional BOOT0 pin, together with option bytes like nBOOT_SEL, nBOOT1, and nBOOT0, had served their purpose well for years.

This new mechanism not only complicates things, but also reduces the number of usable GPIOs - especially on smaller packages - by forcing them OUT off a high-impedance state on the first power-up.

 

waclawek.jan
Super User

> This new mechanism not only complicates things, but also reduces the number of usable GPIOs - especially on smaller packages - by forcing them OUT off a high-impedance state on the first power-up.

The intention with the empty-check bootloader empty presumably was to increase number of usable pins, by omitting BOOT0. I agree that this may create a less clean situation, if the users are not aware of all the consequences. One way how to tackle this is to perform initial programming under hardware NRST pin is held low. This of course may have its implications on the hardware design (at least that pin has to be brought out to programming header, but also the programming environment has to be capable of programming under reset), too.

The real problem is in the fact that the bootloader pulls some of the pins up/down using the nominally 40kOhm pull, but, even more disturbingly, that it pulls some if the pins *hard* (due to what I consider to be a flawed SPI-bootloader implementation). AN2606 does not make a very good job in warning to this, this being decribed only in a footnote to the "resources" table, and also in a rather cryptic formulation involving reference to the internal actions of the bootloader ("...as soon as the bit DMATx enable on SPI CR2 register is set to 0x1") where in fact DMAT is enabled in the SPI bootloader unconditionally (as can be checked by single-stepping or disassembling the bootloader).

I agree that this issue is grave enough so that users are clearly notified of it in the datasheet, at around the pinout table; and/or in the GPIO chapter of RM. A simple reference to AN2606 would suffice, would AN2606 clearly and unambiguously list which pins are used - pulled, hard or weak -  and how.

JW

Version history
Last update:
‎2025-08-13 9:15 AM
Updated by:
Contributors