Hi all,
I have a Second Bootloader and a burned user application (checked for correct burning). I want to exit bootloader and jump to the user application. After performing the void jump_to_application function (uint32_t applicationAddress, uint32_t stackPointer), the processor is reset immediately. Can anyone advise me on what I am doing wrong? I followed AN12604SW. The code is located in the SPI flash.
I use i.MXRT1061, MCUXpresso11.3, SDK2.9.1 and custom board.
My code:
#define APPLICATION_ADDRESS 0x60040000
#define STACK_POINTER 0x60040004
//! @brief Exits bootloader and jumps to the user application.
//AT_QUICKACCESS_SECTION_CODE(void jump_to_application(uint32_t applicationAddress, uint32_t stackPointer));
void jump_to_application(uint32_t applicationAddress, uint32_t stackPointer)
{
shutdown_cleanup(kShutdownType_Shutdown);
// Create the function call to the user application.
// Static variables are needed since changed the stack pointer out from under the compiler
// we need to ensure the values we are using are not stored on the previous stack
static uint32_t s_stackPointer = 0;
s_stackPointer = stackPointer;
static void (*farewellBootloader)(void) = 0;
farewellBootloader = (void (*)(void))applicationAddress;
// Set the VTOR to the application vector table address.
SCB->VTOR = (uint32_t)0x60040000;//APP_VECTOR_TABLE; 0x60000000 0x60040000
// Set stack pointers to the application stack pointer.
__set_MSP(s_stackPointer);
__set_PSP(s_stackPointer);
// Jump to the application.
farewellBootloader();
// Dummy fcuntion call, should never go to this fcuntion call
shutdown_cleanup(kShutdownType_Shutdown);
}
void shutdown_cleanup(shutdown_type_t shutdown)
{
// If we are permanently exiting the bootloader, there are a few extra things to do.
if (shutdown == kShutdownType_Shutdown)
{
// Turn off global interrupt
///lock_acquire();
__disable_irq();
// Shutdown microseconds driver.
///microseconds_shutdown();
// Disable force ROM.
#if defined(RCM_FM_FORCEROM_MASK)
RCM->FM = ((~RCM_FM_FORCEROM_MASK) & RCM->FM) | RCM_FM_FORCEROM(0);
#elif defined(SMC_FM_FORCECFG_MASK)
#if defined(SMC0)
SMC0->FM = ((~SMC_FM_FORCECFG_MASK) & SMC0->FM) | SMC_FM_FORCECFG(0);
#else
SMC->FM = ((~SMC_FM_FORCECFG_MASK) & SMC->FM) | SMC_FM_FORCECFG(0);
#endif
#endif // defined(RCM_FM_FORCEROM_MASK)
// Clear status register (bits are w1c).
#if defined(RCM_MR_BOOTROM_MASK)
RCM->MR = ((~RCM_MR_BOOTROM_MASK) & RCM->MR) | RCM_MR_BOOTROM(3);
#elif defined(SMC_MR_BOOTCFG_MASK)
#if defined(SMC0)
SMC0->MR = ((~SMC_MR_BOOTCFG_MASK) & SMC0->MR) | SMC_MR_BOOTCFG(3);
#else
SMC->MR = ((~SMC_MR_BOOTCFG_MASK) & SMC->MR) | SMC_MR_BOOTCFG(3);
#endif
#endif // defined(RCM_MR_BOOTROM_MASK)
init_interrupts();
// Set the VTOR to default.
SCB->VTOR = 0;//kDefaultVectorTableAddress;
// Restore clock to default before leaving bootloader.
//configure_clocks(kClockOption_ExitBootloader);
// De-initialize hardware such as disabling port clock gate
///deinit_hardware();
LPUART_Deinit(LPUART1_PERIPHERAL);
// Restore global interrupt.
//__enable_irq();
#if BL_FEATURE_BYPASS_WATCHDOG
// De-initialize watchdog
bootloader_watchdog_deinit();
#endif // BL_FEATURE_BYPASS_WATCHDOG
}
// Memory barriers for good measure.
__ISB();
__DSB();
}
Thank you for answer.
Jaroslav C.
Solved! Go to Solution.
Hi,
The problem is solved. I finally used the function:
#define BL_APP_VECTOR_TABLE_ADDRESS 0x60040000
#define APP_VECTOR_TABLE ((uint32_t *)BL_APP_VECTOR_TABLE_ADDRESS)
void goToApp()
{
static void (*farewellBootloader)(void) = 0;
farewellBootloader = (void (*)(void))(APP_VECTOR_TABLE[1]);
SCB->VTOR = (uint32_t)APP_VECTOR_TABLE;
__set_MSP(APP_VECTOR_TABLE[0]);
__set_PSP(APP_VECTOR_TABLE[0]);
farewellBootloader();
}
Jaroslav C.
Hi,
The problem is solved. I finally used the function:
#define BL_APP_VECTOR_TABLE_ADDRESS 0x60040000
#define APP_VECTOR_TABLE ((uint32_t *)BL_APP_VECTOR_TABLE_ADDRESS)
void goToApp()
{
static void (*farewellBootloader)(void) = 0;
farewellBootloader = (void (*)(void))(APP_VECTOR_TABLE[1]);
SCB->VTOR = (uint32_t)APP_VECTOR_TABLE;
__set_MSP(APP_VECTOR_TABLE[0]);
__set_PSP(APP_VECTOR_TABLE[0]);
farewellBootloader();
}
Jaroslav C.