2024-06-05 04:30 PM
I am currently working on a project using the STM32U575ZI-Q microcontroller. I have successfully developed a bootloader for my application. However, I am encountering a critical issue where the program fails to jump from the bootloader to the main application.
Issue Details:
Request:
I would greatly appreciate your assistance in diagnosing and resolving this issue. Specifically, I am looking for guidance on:
Attachment:
I have inseeted the relevant sections of my bootloader and application code for your reference and analysis.
Thank you for your support.
void JumpToApplication(uint32_t address) {
SendStatusMessage("Gonna Jump to Application\r\n");
printAddress(address);
// If the function returns false, return to the bootloader loop
if (!WaitForInputAndReturnToBootloader()) {
return;
}
// Get application's stack pointer (first word of the application start address)
uint32_t appStack = *(volatile uint32_t*)address;
// Get application's reset handler address (second word of the application start address)
void (*app_reset_handler)(void) = (void(*)(void)) (*(volatile uint32_t*)(address + 4));
printAddress((uint32_t)app_reset_handler);
// Validate appStack and app_reset_handler addresses
if ((appStack & 0xFF000000) != 0x20000000 || ((uint32_t)app_reset_handler & 1) == 0) {
SendStatusMessage("Invalid stack pointer or reset handler address.\r\n");
return;
}
// Set main stack pointer to the value at the start of the application address
__set_MSP(appStack);
SendStatusMessage("App Stack\r\n");
printAddress((uint32_t)appStack);
SendStatusMessage("App Reset Handler\r\n");
printAddress((uint32_t)app_reset_handler);
// Clear the terminal screen
ClearTerminalScreen();
// Set Vector Table Offset Register to the application's vector table address
SCB->VTOR = address;
// SendStatusMessage("SCB->VTOR\r\n");
// printAddress((uint32_t)SCB->VTOR);
// Enable all interrupts
__enable_irq();
// Jump to application's reset handler
app_reset_handler(); // Call the app reset handler
// If the app_reset_handler returns, there's an issue
SendStatusMessage("Failed to jump to application.\r\n");
}
Best regards,
Cristopher Bohol
2024-06-15 11:36 PM
I am also facing the same issue. Have you found any solution for this?
2024-06-16 02:40 PM
Why do you develop a bootloader when it is already there?
OK, when it comes to your own bootloader, here my thoughts what to check:
When it comes to the question like "jumping to bootloaded code as user code" you might consider how the vector table is set (used by your user code) and what the stack (and SP register) is. Also to bear in mind the caches (used during bootloading and jumping to user code) might be invalidated.
Why not using the BOOT pin and the STM bootloader in the chip? Having your own bootloader, maybe for OTA firmware updates (see Arduino bootloader used often on STM boards) and make sure that jumping to user code works like after core reset (at least to set vector table, stack, esp. SP register).
BTW: how do you jump after bootloading to user code? The correct way would be this: read the vector table provided by the application (user) code. Read the second word (first is SP register init, second is Reset_Handler entry). Read this second word in vector table as entry address for your user code (Reset_Handler). Jump to it, via jumping with register value, the address read first from vector table.
Don't forget to think about the stack (which one?) and to set SP register. If you keep going with stack defined for bootloader - you are maybe "out of stack".
And, if you do not relocate the vector table - you will use still the bootloader vector table (but not the one provided with your user code).
2024-06-16 03:03 PM
BTW: do you know, when using a NUCLEO board - it comes with an ARM mbed bootloader?
When you have a NUCLEO board with onboard STM debugger chip - it provides usually also an USB memory device (an external USB memory device pops up on host PC).
When you drag and draw now a new FW bin file onto this "USB memory device": it should flash this new user application and boot it (if this USB memory device is not disabled via updating the ST-Link SW and selecting the other option).
So, any STM32 have already a bootloader integrated (see BOOT pin options), a NUCLEO board comes with a very convenient way to flash a new FW (see USB memory device) and when you write your own bootloader: check Arduino bootloaders for a STM chip and make sure to set all set properly before you jump to the new user/application code: SP and stack base/size, vector table, caches invalidated...