According to this, seems like stm32 boot process is as follows:

  1. Check if FLASH is blank. if yes, goto bootloader mode
  2. Check if BOOT0 pin is asserted. if yes, goto bootloader mode
  3. goto Program mode

My problem is the first condition on first boot.

when i buy some MCUs fresh and blank, and i solder them to my product boards that i plan on programming them in-system via SWD protocol later ( so i don't need bootloader anyways ) I tie BOOT0 pin low in pcb. but seems like its being ignored on the first boot when the flash is blank and the bootloader code gets executed anyways.

Lets say i planed to use a GPIO pin as input, which happens to be the same pin that bootloader uses as USART_TX (or USB or anything else) so if the code gets executed, it becomes a PUSH_PULL OUTPUT, whereas its also externally driven by something else on the PCB because it was considered an input in product design.

thats quiet a short there.

Do i have to consider these? is this even true?

Seems like there is some unclear variation between different series too...

  • 1
    \$\begingroup\$ Which exact STM32 chip you are talking about? There's dozens of different models, and not single one of them I know runs the bootloader automatically if BOOT0 is low, regardless of blank flash. Some of the models do if flash is blank. \$\endgroup\$
    – Justme
    Commented Aug 11, 2020 at 17:19
  • \$\begingroup\$ It's an interesting question you could test with an EVB if the bootloader will drive a UART output to idle level before it gets a signal on the corresponding input. Putting in some series resistors on pins of potential conflict could be an idea. Of course UART isn't the only interface, but its one of the ones more likely to assert a level without being querried. Really the best practice might be to save the pins the bootloader wants to use as a UART output to use as your primary debug UART... or at least avoid using them for grossly conflicting purposes like an input. \$\endgroup\$ Commented Aug 11, 2020 at 18:48
  • \$\begingroup\$ the newer stm32s dont default to using a boot0 externally you have to do a bit of work, but they still boot into the bootloader if the application flash is empty. If it boots into the bootloader you can use SWD just fine to program the chip yes? I dont understand the problem you are having. for the ones with a boot0 it is documented that you need an external resistor. what part of the st documents do you not understand? \$\endgroup\$
    – old_timer
    Commented Aug 12, 2020 at 1:38
  • \$\begingroup\$ some of them you can program an internal non volatile register to not permit the boot0 pin from working. also documented in the st documentation, what part of that did you not understand? What specific part is this? \$\endgroup\$
    – old_timer
    Commented Aug 12, 2020 at 1:39

1 Answer 1


First off, there are lots of different versions of the bootloader and patterns how you enter each of them implemented in the various families of the STM32. Indeed newer parts have a pattern to enter the bootloader which matches your description.

The main document to read carefully is the application note AN2606 about the bootloader.

One main recommendation is the following:

It is recommended to keep the RX pins of unused bootloader interfaces (USART_RX, SPI_MOSI, CAN_RX and USB D+/D- lines if present) at a known (low or high) level at the startup of the bootloader (detection phase). Leaving these pins floating during the detection phase might lead to activating unused interfaces.

Which of course doesn't directly tells us what happens with pins, but activating a bootloader interface is not what you want in your case.

Pay special attention to the pins you need for SWD. Often those are shared with USART2 functionality and accidently activating that interface will lock you out of SWD.

Then there are tables for each device which tells you which interface maps to which pin and functionality and which are used as input and output.

I agree, that it isn't clear at which state the pins are while the bootloader is not using that interface actively.

For the USART TX the text usually sounds like this: "PA9 pin: USART1 in transmission mode", so is it only an output when it is in transmission mode?

For the SPI MISO it goes like this: "PA6 pin: Slave data output line, used in pushpull pull-down mode", which could indicate that it is in a input state when not in use, why else would there be a pull-down resistor active?

Similar thing with CAN TX: " PB9 pin: CAN1 in transmission mode": sounds like it might be disable when CAN is not in transmission mode.

Like Chris Stratton suggested in the comments I took my Nucleo with the STM32L452RE and erased the flash and it behaves like you described and ended up in the bootloader.

The board is powered by a lab supply with current limit on.

I then hooked up a wire from GND or 3V3 and connected it to the output pins of the bootloader interfaces and got the following - not encouraging - results:

  • USART TX: high impedance
  • SPI MISO: driven high
  • CAN TX: driven high

My take on it:

  • Check exactly which behavior applies to your chip

If you end up in the bootloader:

  • do not use conflicting signal directions (the behavior I observed might change if there is an update in the bootloader)
  • make sure it does not use a interface which blocks SWD by keeping the input pins for that interface at a known constant level
  • \$\begingroup\$ Yes that's the case for some STM32s, especially the new ones. Need to be careful with the IOs state in bootloader mode or make sure you always to hold the nRST low and program the MCU when powering your PCB for the first time. There's an article about it here community.st.com/s/article/Empty-check-mechanism-on-STM32 - I particularly dislike the empty flash approach and having to use Boot0 pin the correct method if you need to access the factory bootloader. \$\endgroup\$
    – Talk2
    Commented Mar 7, 2023 at 11:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.