2025-02-25 11:00 PM - last edited on 2025-02-26 1:38 AM by mƎALLEm
ISSUE: STM32F7 Custom Bootloader - Main Application Not Running After Jump
Details:
Bootloader Memory Definition:
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 320K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K
QUADSPI (r) : ORIGIN = 0x90000000, LENGTH = 16M
Application Memory Definition:
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 320K
FLASH (rx) : ORIGIN = 0x8020000, LENGTH = 896K
QUADSPI (r) : ORIGIN = 0x90000000, LENGTH = 16M
Validation Points:
Bootloader erase & write operations are working correctly.
Custom bootloader successfully writes the application code to both internal and external segments.
A test application that prints text ("I am application") works properly after jumping from the bootloader.
Debug points :
1 > memory utilization by main application
RAM : ORIGIN = 0x20000000, utilization = 320 K
FLASH : ORIGIN = 0x8020000, utilization = 896 K
QUADSPI : ORIGIN = 0x90000000, utilization = 5.18 M
2 > Jump steps after writing application (by custom bootloader)
/*********************************************************************************************
if(gParsePacketData.data[0] == BOOT_STATUS)
{
#define APP_ADDRESS 0x08020000
typedef void (*pFunction)(void);
pFunction JumpToApplication;
uint32_t JumpAddress;
int Temp = 0 ;
vc_prepare_packet_and_send(&huart6,FEEDBACK_COMMAND,FEEDBACK_SUCCESS,&Temp,sizeof(Temp));
// Disable interrupts
__disable_irq();
// Deinitialize peripherals and clocks if needed
// Set vector table to application address
SCB->VTOR = APP_ADDRESS;
// Read the application's stack pointer address
__set_MSP(*(volatile uint32_t*)APP_ADDRESS);
// Get the application's reset vector (entry point)
JumpAddress = *(volatile uint32_t*) (APP_ADDRESS + 4);
JumpToApplication = (pFunction) JumpAddress;
// Enable interrupts (optional, the application should handle it)
__enable_irq();
// Jump to application
JumpToApplication();
/**********************************************************************************/
We would be grateful for any guidance or suggestions you can provide.
2025-02-25 11:23 PM
2025-02-25 11:31 PM
Thank you for your valuable reply, but the changes have already been made and tested.
2025-02-26 5:57 AM
I am using a bootloader that checks checksum and jumps to it, using struct and code below. Make sure not to have any DMA or interrupts being active when jumping.
// Struct for relaxed addressing
typedef struct
{
void *stack; //0
void (* appentry)(void); //1
u32 pad[5]; //2 3 4 5 6
void (* frestrict)(int code); //7
u32 checksum; //8
u32 flashend; //9
u32 version; //10 0x08000028
} APPINFO;
// jump to application if valid
// called also after successfull firmware upgrade
#define APPSTART 0x08020000
void checkapp(bool reset)
{
u32 xs = 0;
const u32 *bin = (u32 *)(APPSTART);
const APPINFO *ai = (APPINFO *)bin;
u32 fend = ai->flashend;
if((fend < APPSTART) || (fend > 0x080E0000) ) return; // should be reasonable, last sector for storage?
while(bin < (u32 *)fend) xs += *bin++;
if(xs == 0)
{
if(reset) ResetPeriph();
ai->appentry(); // bye!
}
}
I am
2025-02-26 6:29 AM
On the app side, I would avoid doing any system clock (RCC) re-initialization, or that of the pins and the QSPI / External memory interfaces that the loader has already brought up to operational status.
2025-02-26 6:38 AM
> A test application that prints text ("I am application") works properly after jumping from the bootloader.
If a test application works, but your main app doesn't, doesn't that suggest a bug with your main application? Certainly it means the jump is working as intended.
Debug the code, let the jump happen, pause the code and examine the state of the system. Could be that you're in an interrupt that now points to an invalid location. You don't actually disable any interrupts. Only temporarily.
How to jump to system bootloader from application ... - STMicroelectronics Community
2025-02-26 11:54 AM
Prioritize getting working HardFault_Handler() and Error_Handler() in both loader and app, that can give visible and definitive information if they arrive there. For the latter a source file and line would help pin things down quickly.