cancel
Showing results for 
Search instead for 
Did you mean: 

Bizarre bootloader invocation every other debug session

indigoandblack
Associate II

I'm experiencing a very, very strange behavior when running debug sessions in STM32CubeIDE. Sequential sessions alternate between correct execution of my main() entry point (and execution stops there, as expected) and unexpected entry into the bootloader.

Everything has worked absolutely correctly up until just a few days ago. Before that, I last compiled and programmed firmware maybe a week and a half ago. I made a git branch at that point to capture the state of the software prior to making changes for a new PCB revision. Now, after experiencing this issue with new code, I've even switched back to that historical branch, and that now also exhibits the issue. I've also rebooted and power cycled my programmer and boards. I have two PCBs, and they both behave the same way.

I'm using STM32CubeIDE v. 1.19.0 build 25607_20250703_0907.

Target is an STM32L431CC (CCT6). Program/debug is via an ST-LINK/V2 and SWD. Nothing has changed in my debug configuration (and reset behavior is "connect under reset", and I have the "set breakpoint at" checkbox checked, with the symbol "main").

On the board, BOOT0 (pin 44) is tied to GND with 10 KΩ.

Nothing has changed with the hardware or the software. And I made the historical branch after having programmed and tested the software. I also verified that in the "failure" case, my reset handler is in fact not being called - a breakpoint at the first instruction of the handler gets hit every other session.

This is the typical sequence I see:

1) I perform a clean and a build to verify compilation (debug configuration, not release).

2) I start a debug session (nothing gets rebuilt). In the debug console, I see everything as expected, up to the message, "Download verified successfully". However, execution does not halt in main(), and the code is running. If I then suspend execution, I'll see an address like 0x1fff2cdc. That's bootloader territory!

3) I terminate and relaunch (nothing gets rebuilt). I see everything as expected, but this time execution halts just inside of main(), as it's supposed to.

4) Behavior in subsequent relaunches alternates between (2) and (3).

This one has me flummoxed. I've found nothing in the forums or elsewhere online that's similar.

Has anyone else experienced anything remotely similar?? (And many thanks in advance to anyone taking the time to share some ideas.)

 

 

 

7 REPLIES 7

Power cycling and reset are subtly different. Some of this stems from security and integrity against attack vectors.

The bootloader comes up and checks if the vector table is viable, and it can latch that regardless of BOOT0 pin state.

The flashing and debugging can lead to latched conditions. 

 

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

I get there's a difference. However I'm really not certain what you're talking about. What do you mean "the bootloader comes up"? And "is viable"?

I'm not aware of any execution of bootloader code in any circumstances on a pin reset (short of asserting BOOT0). That doesn't seem to make any sense. Could you point me to any documentation?

Incidentally, for you and for anyone else reading, I've also tried building and debugging from an absolutely fresh checkout, and I have the same behavior. Strictly alternating, jump-into-bootloader and halt-in-main.

This makes no sense.

Also, my FLASH_OPTR value is 0xFFFF'F8AA.

The RM (RM0394) says the production value of that register is 0xFFEF'F8AA. (The difference is with bit 20, a reserved bit.)

 

waclawek.jan
Super User

Always post which STM32 model are you using (RM0394 partially gives it away, but for example the following text does not apply to the "mid-range" 'L4).

@Tesla DeLorean  refers to the infamous PEMPTY mechanism.

waclawekjan_0-1754917336505.png

 

The exact mechanism with debugger depends heavily on the particular debugger and its exact behaviour.

Try setting the nBOOT0/nSWBOOT0 option bits to 1/0 respectively.

JW

Always post the STM32 model? You mean like "STM32L431CC" as in my original post?

I understand what the PEMPTY mechanism is. This behavior occurs during the launch of a debug session, after program/verify and debugger script release of reset. The flash by definition is not empty.

Edit, added:

Plus, currently (this is the manufacturer original setting) nBOOT0 is 1. I don't want to set nSWBOOT0 to 0, because that will cause the BOOT0 value to be taken from the nBOOT0 bit and I'll have the bootloader all the time. I need nBOOT0 / nSWBOOT0 to be set as they are now (original default) as 1 / 1. When nSWBOOT0 is 1, the BOOT0 value comes from the PH3/BOOT0 pin, which is what I want.

 

> model

I've overlooked that, sorry.

> The flash by definition is not empty.

It may be the case at the point of "launch", but the issue is, that the PEMPTY bit is not cleared by any other but power-on reset. Or OBL_LAUNCH; but what any debugger does is often undocumented in the details.

> I don't want to set nSWBOOT0 to 0, because that will cause the BOOT0 value to be taken from the nBOOT0 bit and I'll have the bootloader all the time.

If nBOOT is 1, you won't have the bootloader ever. OTOH, the nSWBOOT0=0&BOOT0=0 combination *does get* overridden by PEMPTY. See the table I've posted above.

JW

Ok, so, for the benefit of the reader: I just finally managed to find two more old posts on exactly this issue, and they both turned out to be from here (!!):

Intermittent Break at address "0x1fff51f4" with no debug... 

and

Debug launch appears to end up in bootloader 

 

I see that you (JW, not the reader now) had replied back then as well.

I may end up just setting my nSWBOOT0 option bit to 0. I was hoping to keep open the option of using the bootloader, but this misbehavior is really seriously harming my calm right now.

JW, the biggest thing I don't get is this: since the PEMPTY condition is latched on power up (not just a reset - is that correct?), why is it that, after power cycling a board that was just programmed, the first debug session I start will end up in the bootloader? (The next relaunch is correct; the one after that goes into the bootloader; etc.)

This whole thing is infuriating because I've never, ever experienced this. Ever! And now, all of a sudden, I can't NOT experience it. :(

Plus, this misbehavior isn't one of those "well, you have to consider these weird edge conditions" situation - it's incorrect behavior, and apparently (according to the "intermittent break" post) it has occurred and been addressed with patches from ST in the past.

Edit:

I was incorrect in an earlier message that setting nSWBOOT0 to 0 would result in the bootloader executing all the time. That would be true if nBOOT0 was set to 0, but mine is not. I verified correct behavior after changing the bit.