cancel
Showing results for 
Search instead for 
Did you mean: 

Empty check mechanism on STM32

Martin HUBIK
Associate III

1) GPIOs are not in High impedance after reset
2) User code is not executed after programming empty device

On most STM32s GPIO after reset are configured in high impedance except for Debug pins. Some STM32s implement so called empty check mechanism, which force the MCU to boot into System memory (ST bootloader) when the content of the first address in flash is empty. The ST bootloader configures all supported communication interfaces and associated GPIOs. This allows easy programming of virgin devices but might cause problems when programing on assembled PCB. It might lead to additional current consumption or in worst case to short circuit if Bootloader pins are connected to GND or VDD. After successful programing, certain procedure must be followed to boot into freshly programmed User flash. Simply resetting the device is not enough.
In the table below you can see the availability of Empty check by STM32 series.
 
STM32 Series
 
Empty checkArm
Cortex®
STM32 F0 M0
STM32 F1 M3
STM32 F2 M3
STM32 F3 M4
STM32 F4 M4
STM32 F7 M7
STM32 L0 M0+
STM32 L1 M3
STM32 L4 M4
STM32 L5 M33
STM32 H7 M7/M4
STM32 G0 M0+
STM32 G4 M4
STM32 WB M4/M0+

127.png
Full list of devices
  • STM32L4+
  • STM32WB
  • STM32G0
  • STM32F04x
  • STM32F09x
  • STM32F070x6
  • STM32F030xC
  • STM32L011x/ STM32L021x
  • STM32L41x/ STM32L42x
  • STM32L43x/ STM32L44x
  • STM32L45x/ STM32L46x

Empty check mechanism is used when BOOT0 is configured to select User Flash memory as target boot area (BOOT0 pin tied to GND). When BOOT0 pin is tied High, the boot selection depends on BOOT1 pin or nBOOT1 option bit.
To prevent execution of ST Bootloader on empty device
  •  
  • Keep nRST signal low to keep the device under reset
  • Connect with debugger Under reset. It enables connection to the target using a reset vector catch before executing any instructions, in other words before System bootloader initializes any peripherals and GPIOs
  • Program User flash
  • Clear the Empty check bit to boot from User flash on next reset

Empty check bit is cleared by HW on Power on reset or by reloading Option bytes (see OBL_LAUNCH in reference manuals). There are two additional possibilities on specific devices
  • On STM32G0 and STM32WB it is possible to overwrite the empty check flag in FLASH_ACR register
  • 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.

Tip: On devices with nSWBOOT0 or nBOOT_SEL option bit (like STM32WB, STM32L4, STM32G0) it is possible to force boot from Main flash by using nBOOT0 option bit instead of BOOT0 pin.

This can be achieved by following Option byte configuration:
-nSWBOOT0 = 0 (BOOT0 signal is defined by nBOOT0 option bit) nBOOT0 = 1, for STM32L4 and STM32WB.
-nBOOT_SEL = 1 (BOOT0 signal is defined by nBOOT0 option bit) nBOOT0 = 1, for STM32G0.

For more information, please also check “STM32 boot and startup tips" MOOC on this link

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:
‎2020-08-12 6:32 AM
Updated by: