2
\$\begingroup\$

I am writing a small application to start a bootloader that checks simple conditions and then jumps to the application memory. The application seems to crash and I am unable to figure out the reason and the debugger is throwing:

Break at address "0x8000d00" with no debug information available, or outside of program code.

I started the project from scratch on STM32Cube IDE for the STM32F405 microcontroller with 1Mb of flash. The bootloader starts fine - it blinks an LED few times and has to jump to an application which also blinks LED at different frequency and reads button input to toggle LED. Right now, the bootloader sequence loads and then it stops - nothing from the application code.

The bootloader is located at 0x08000000 and I allocated 64Kb. The application space is starting from 0x08020000 and is allocated 768Kb.

This is how I am jumping to the application space from the bootloader program:

void (*app_reset_handler)(void) = (void*)(*((volatile uint32_t*) (0x08020000 + 4U)));
app_reset_handler();    

In my application program, I have defined the flash base address field:

#define VECT_TAB_OFFSET         0x00020000U

and defined the memory definitions for flash:

FLASH    (rx)    : ORIGIN = 0x08020000,   LENGTH = 768K

I have followed the same steps for a previous implementation on F401 which seems to work fine. Any ideas how to debug this issue?

\$\endgroup\$
3
  • \$\begingroup\$ More actual code is needed. Why are the vectors set to 00020000h if everything else is officially located at 08020000h? What if the problem is the application, not the bootloader? How you linked the app? \$\endgroup\$
    – Justme
    Commented Dec 29, 2021 at 19:49
  • \$\begingroup\$ Just recently wrote some code for STM32 UART bootloader. Discovered a weird quirk where it would nack/break if you sent it data without gaps between consecutive bytes. Seems like the interrupt handler for the baked in bootloader has a lot of overhead, prevents gapless UART transmissions. Might be your problem? \$\endgroup\$
    – Ocanath
    Commented Dec 29, 2021 at 23:25
  • \$\begingroup\$ need to see the disassembly, this is a thumb machine... \$\endgroup\$
    – old_timer
    Commented Oct 2, 2023 at 15:27

1 Answer 1

1
\$\begingroup\$

This is what works for me on STM32L4. You may be missing the step of switching to the application's stack before jumping to the application.

Other things to note: My application is at a different offset from yours. The boot program uses VECT_TAB_OFFSET of 0 whereas the application uses the offset. Ensure your application's linker file puts the reset vector table at the beginning of the section (i.e. first thing at the offset).

#ifdef BOOT
#define VECT_TAB_OFFSET  0x00 /*!< Vector Table base offset field.
                                   This value must be a multiple of 0x200. */
#else
#define VECT_TAB_OFFSET  0x80000
#endif

#define MAIN_PROG_BASE_ADDR 0x08080000U

typedef void (*pFunction)(void);

void JumpToMainProgram()
{
    pFunction MainProgram = (pFunction)(*(uint32_t*)(MAIN_PROG_BASE_ADDR + 4));
    
    // Switch to main program's stack.
    __set_MSP(*((uint32_t*)(MAIN_PROG_BASE_ADDR)));

    // Jump to main program.
    MainProgram();
}

My boot program first validates the main application and then simply calls the JumpToMainProgram() function.

\$\endgroup\$

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.