2024-10-01 09:39 PM - last edited on 2024-10-04 03:00 AM by Amel NASRI
Dear STM32 Community,
I am currently working on a project using the STM32F072RBT6 microcontroller, where I have implemented a custom bootloader to load an application program into flash memory. However, after the bootloader successfully writes the application binary, the stack pointer does not correctly jump to the application’s address, and the application fails to execute.
MCU Model: STM32F072RBT6 Bootloader
Functionality: The bootloader receives the application binary and writes it to flash memory at the designated application address.
Application Flash Address: 0x08004000
Problem: After the bootloader completes, I attempt to jump to the application by setting the stack pointer and program counter accordingly, but the application does not start. It appears that the stack pointer is not correctly set to the application's address.
Jump Code in Bootloader:
static void goto_application(void){
void (* app_reset_handler)(void) = (void *)(*(volatile uint32_t *) (0x08004000 + 4));
__disable_irq();
__set_MSP((*(volatile uint32_t *)0x08004000));
__enable_irq();
app_reset_handler();
}
Solved! Go to Solution.
2024-10-09 04:30 AM
Dear STM32 Community,
I hope this message finds you well. I wanted to take a moment to express my sincere thanks to everyone who contributed their time and expertise to help me with my issue. I’m happy to report that I’ve successfully solved the problem!
The issue was related to the HAL_Delay function in my application code. I was using HAL_Delay incorrectly, which caused my application code to get stuck. After going through the suggestions and feedback from the community, I was able to identify and resolve the root cause.
Thank you once again for your invaluable support and insights. I appreciate being part of such a knowledgeable and helpful community!
2024-10-02 02:51 AM
So it is set to WHAT exactly?
The use of auto/local variables whilst changing the SP is also seriously ill advised.
Look at the generated code.
Do this stuff in assembler, or have the apps Reset_Handler set SP when you get there.
The F0 is also a CM0 so no SCB->VTOR, vectors need to get copied to RAM and remapped.
.
2024-10-02 05:23 AM
Are interrupts active in the bootloader? You'll need to disable them first.
When it "doesn't start" where is execution at?
There is nothing wrong with the code you've presented. The problem lies elsewhere. General code for jumping to the bootloader can be found here. You can adapt it for jumping to the application.
How to jump to system bootloader from application ... - STMicroelectronics Community
2024-10-02 06:06 AM - edited 2024-10-02 06:06 AM
Besides of possible reasons mentioned by TDK and Tesla... consider effects of compiler optimization.
Variable app_reset_handler is local and it may be allocated on the stack.
Then you move the stack pointer. This is what __set_MSP does. It changes the stack pointer.
Guess what happens to the app_reset_handler variable?
2024-10-02 06:49 PM
Exactly. The bootloader code that STM32CubeMX generates suffers from this same issue. When optimizations are enabled (with AC6 anyway) it works fine. But crashes when using -O0.
2024-10-03 10:55 PM - edited 2024-10-03 11:24 PM
@mbrossett "Thanks for the suggestion! I already tried changing the optimization level, but unfortunately, the same problem occurs even with different settings, including -O0. It seems like the issue persists regardless of the optimization level. Any other ideas on what could be causing this?"
2024-10-03 11:10 PM
@Tesla DeLorean "Thanks for the input! I tried remapping the vectors for the STM32F032RBT6 and handling the reset in the application, but it still gets stuck somewhere in the code. Any ideas on what might be causing this?"
2024-10-03 11:16 PM
@TDK "Yes, I’m using the UART receive interrupt in the bootloader to receive the application binary file. After that, I want to jump from the bootloader to the application code. Do I need to disable interrupts before jumping? Any advice on handling the transition would be helpful!"
2024-10-03 11:23 PM - edited 2024-10-03 11:24 PM
@Pavel A. "Thanks for the explanation! It looks like the app_reset_handler might be getting stuck in the application code, possibly because it's stored on the stack and I'm changing the stack pointer with __set_msp. Could you clarify what I should do in this case? Should I make app_reset_handler a global variable, or is there a better way to handle this transition?"
2024-10-04 06:13 AM
It can be a global variable or optimized so that it is in a register rather than on stack. Or use inline assembly.