Unable to Jump Between Bootloader and Application using stm32u575
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:
- Problem Statement:
- The bootloader does not transition to the application despite the address being correctly set.
- Instead of jumping to the application, the program hangs indefinitely.
- Steps Taken:
- Verified the application start address in the bootloader code.
- Ensured that the vector table is correctly pointed to the application start address.
- Checked for any potential interrupts that might interfere with the jump process.
- Observations:
- The bootloader code executes correctly up to the point where it should jump to the application.
- Upon attempting to jump, the program execution halts, and no further operations occur.
- Environment:
- IDE/Toolchain: STM32CubeIDE
- Microcontroller: STM32U575ZI-Q
- Bootloader and Application: Custom code developed using STM32CubeIDE.
Request:
I would greatly appreciate your assistance in diagnosing and resolving this issue. Specifically, I am looking for guidance on:
- Verifying the correct setup for transitioning control from the bootloader to the application.
- Identifying any potential pitfalls or common issues that might cause the program to hang during this transition.
- Recommended debugging steps or tools that could help in pinpointing the root cause of this problem.
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
