2
\$\begingroup\$

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();
}
\$\endgroup\$
6
  • \$\begingroup\$ Welcome to SE/EE! Please take the tour to learn how this site works, and read "How to Ask" and other pages of the help center. While such questions are commonly asked on Stack Overflow, it is fine here, too, I assume. -- Did you check the resulting machine code? You can look at a listing, a disassembly, or use your debugger. Please edit your question to clarify and to add the disassembly of the function you show. \$\endgroup\$ Commented Oct 4 at 7:16
  • \$\begingroup\$ How have you confirmed that it isn't set correctly? There are many other things that could go wrong too. \$\endgroup\$
    – Justme
    Commented Oct 4 at 7:59
  • 1
    \$\begingroup\$ The cast is incorrect, it should be ... = (void (*)(void)) (0x08004000 + 4);. Converting function pointers to void* or vice versa is undefined behavior. Converting integers to function pointers is OK though, if the compiler allows it and if the address is corresponding to the function alignment requirement \$\endgroup\$
    – Lundin
    Commented Oct 4 at 11:47
  • 1
    \$\begingroup\$ @Lundin is UB in general, but is well defined in this implementation \$\endgroup\$ Commented Oct 5 at 20:20
  • \$\begingroup\$ @0___________ So not gcc but something else? Hmm. To OP doesn't mention compiler used, so in case of STM32 I'd definitely assume gcc. There is a gcc non-standard extension allowing arithmetic on void pointers and function pointers, which in turn suggests that they must all be boiled down to something like a character pointer internally. -> \$\endgroup\$
    – Lundin
    Commented Oct 9 at 7:38

1 Answer 1

2
\$\begingroup\$

You forgot about one important detail.

  • you have to set the VTOR register to set the vector table to application one.

Also if the application is run from the bootloader it should enable interrupts itself. Otherwise you will have a gray area when interrupts are enabled and call handlers from the the new vector table - but the app did not have time to initialize itself.

Side note:

void (* app_reset_handler)(void) = (void (*)(void))(0x08004000 + 4));
\$\endgroup\$
3
  • \$\begingroup\$ Yes , I already tried VTOR register to set the vector table to application but problem occured. \$\endgroup\$ Commented Oct 7 at 10:51
  • 1
    \$\begingroup\$ @ShyamParmar You don't tell how you tried that. You can't change VTOR without disabling interrupts first in bootloader. And your main app cannot re-enable interrupts before VTOR is set and the environment is up. The startup code will enable interrupts and any pending interrupt will execute from bootloader code or from application code before you change it. \$\endgroup\$
    – Justme
    Commented Oct 9 at 12:51
  • \$\begingroup\$ 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! In my case problem was Hal_Delay() function not working in application code. \$\endgroup\$ Commented Oct 10 at 5:39

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.