cancel
Showing results for 
Search instead for 
Did you mean: 

Debug launch appears to end up in bootloader

Tim Butler
Associate II

I have a NUCLEO-L4R5ZI board with an STM32L4R5ZIT6P MCU. I have been successfully building and debugging using CubeIDE 1.9.0 with a USB connection to the onboard ST -LINK debugger. However, I've suddenly encountered a situation where after the debug load, break at main() and continue sequence, the program doesn't execute and control looks to have ended up in the system boot memory. For example, when suspending execution, the traceback shows:

0x1fff16da

0x1fff2c76

I was wondering if anybody might have any ideas as to what could be happening.

A few more data points:

  • The Flash is being correctly programmed by the debugger. If I power cycle the board, letting it run without the debugger, the program executes properly.
  • I can do a debugger attach on the running program and successfully debug.
  • This happens on more than one board.
  • This appears to be somewhat random, as I have older projects that don't fail.

Thanks and best regards,

Tim Butler

5 REPLIES 5

It's one of these STM32 that latches options at power up, not normal resets.

Make sure SystemInit() is properly mapping SCB->VTOR because the default is zero, and whatever is mapped into the zero address space, which can be ROM, RAM or FLASH, but is likely ROM in this case. Or ensure the mapping is to FLASH via SYSCFG map settings.

There's also perhaps an issue with the Option Bytes on these L4R5's but I'll need to dig up a specific cite.

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

Thanks much for the references, they pointed to me to a much better understanding of what's going on. Just to reiterate, the issue of ending up in the bootloader only happens when using the debugger to program the flash and launch execution, and does not always occur. Here's what I've found out.

  • My BOOT0 pin is tied low and option bit nSWBOOT0 is 1, so indeed the mode is boot from Flash if a valid image is present in Flash, system memory otherwise.
  • In all cases, success or failure, execution begins in Flash (Reset_Handler at 0x800xxxx).
  • In the success case, Flash is mapped at address 0. In the failure case, system memory is mapped at 0.
  • SCB->VTOR is zero. This is the default mode of the CubeMX generated code. It looks like there's some discussion about this strategy here: https://community.st.com/s/global-search/USER_VECT_TAB_ADDRESS
  • So in the failure case, with SCB->VTOR at 0 and the system memory mapped to 0, control vectors off to the bootloader on the first interrupt.
  • I modified SCB->VTOR to point to Flash, and as expected, the error does not occur, even when system memory is mapped at zero.

So I can see ways to work around this, but I still don't understand how a debugger launch can boot from Flash, while system memory is mapped to zero. As you mentioned, maybe it has something to do with the way the system latches the boot0 pin and options while under control of the debugger. In the case where system memory is mapped at zero, SYSCFG_MEMRMP:MEM_MODE is zero upon startup, which is inconsistent. However, if I trace HAL_Init() up to the point where RCC->APB2ENR is set, MEM_MODE changes to 1 (as seen by the debugger), which is consistent with the memory mapping.

I have a reproducible success case and failure case, and I observed that the success case requires the debugger to erase 3 sectors and the failure case 4 sectors. Maybe it's a stretch, but it does indicate a timing difference for the debugger launch sequence and might explain an inconsistent latching of reset conditions in certain cases.

Regards,

Tim

Tim Butler
Associate II

To summarize, the problem entails occasional cases where the CubeIDE debugger programs and boots into Flash (as expected), while the memory at address 0 is remapped to system memory instead of Flash (unexpected). I've verified 2 workarounds:

  1. Define the preprocessor symbol USER_VECT_TAB_ADDRESS, which causes SCB->VTOR to explicitly point to the vector table in Flash. This avoids the transfer of control into the bootloader vector table which is incorrectly mapped at address 0.
  2. Change the option bit nSWBOOT0 to 0. This, in conjunction with option bit nBOOT0 = 1, results in the memory at address 0 being correctly remapped to Flash.

Regards,

Tim

ST really should have used a symbolic link for the vector table rather than the define, that way the linker could do it's job and you wouldn't have to edit multiple files when it changed.

Historically the CMSIS methodology was to set this in SystemInit(), along with initializing the FPU, and external memories, etc. so that the startup code could then initialize the statics properly. Then came HAL/Cube..

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