I am developing a bootloader + application setup on S32K148.
- Bootloader is located at flash start (0x00000000)
- Application is located at 0x00022000
- Application has its own vector table and linker script
- Application runs perfectly when flashed standalone
When the bootloader performs flash erase and copy of the application, the jump to application does not work.
However:
- If I skip erase and copy, the jump works correctly
- jump_to_application() is entered in both cases
- No application print is seen after jump when erase + copy is enabled
Stack pointer and reset handler values look valid
Application vector table is correct
Application runs fine without bootloader
I did not explicitly enable the watchdog in application code
What additional steps are required after flash erase + copy before jumping to the application on S32K148?
Anyone help me with this.
I have attached my linker file script and jump application code below.
Thank you.
Bootloader linker file
MEMORY
{
int_flash_interrupts : ORIGIN = 0x00000000, LENGTH = 0x00000400 /* 1K */ /* Do not change this section */
int_flash_config : ORIGIN = 0x00000400, LENGTH = 0x00000010 /* 16bytes */ /* Do not change this section */
int_flash : ORIGIN = 0x00000410, LENGTH = 0x0001FBF0 /* 128KB total - 0x410 = 0x1FBF0 bytes for bootloader code */
int_sram_results : ORIGIN = 0x1FFE0000, LENGTH = 0x00000100 /* 256bytes */
int_sram : ORIGIN = 0x1FFE0100, LENGTH = 0x0003DF00 /* ~248K */
int_sram_stack_c0 : ORIGIN = 0x2001E000, LENGTH = 0x00001000 /* 4K */
ram_rsvd2 : ORIGIN = 0x2001F000, LENGTH = 0 /* End of SRAM */
}
Application linker file
MEMORY
{
int_flash_interrupts : ORIGIN = 0x00022000, LENGTH = 0x00000400 /* 1K - Application interrupt vectors at 0x00022000 */
int_flash_config : ORIGIN = 0x00022400, LENGTH = 0x00000010 /* 16bytes - Application flash config */
int_flash : ORIGIN = 0x00022410, LENGTH = 0x00063BF0 /* 400KB application area (0x64000 - 0x410 = 0x63BF0 bytes) */
int_sram_results : ORIGIN = 0x1FFE0000, LENGTH = 0x00000100 /* 256bytes */
int_sram : ORIGIN = 0x1FFE0100, LENGTH = 0x0003DF00 /* ~248K */
int_sram_stack_c0 : ORIGIN = 0x2001E000, LENGTH = 0x00001000 /* 4K */
ram_rsvd2 : ORIGIN = 0x2001F000, LENGTH = 0 /* End of SRAM */
}
main.c
EraseApplication();
CopyApplication(DOWNLOADED_APP_START_ADDRESS,APPLICATION_START_ADDRESS,APPLICATION_SIZE);
jump_to_application();
jump_to_application() function
void jump_to_application(void)
{
uint32 app_msp;
application_entry_t app_reset_handler;
/* Print message before jumping */
// printf("jumping to application\r\n");
/* Small delay to ensure message is sent */
// volatile uint32 delay = 100000U;
// while(delay--);
/* Disable all interrupts */
__asm volatile ("cpsid i");
/* Set vector table offset to application's vector table */
S32_SCB->VTOR = APPLICATION_START_ADDRESS;
/* Load application's MSP from first word of vector table */
app_msp = *((volatile uint32*)APPLICATION_START_ADDRESS);
/* Load application's Reset_Handler address from second word of vector table */
app_reset_handler = (application_entry_t)(*((volatile uint32*)(APPLICATION_START_ADDRESS + 4U)));
/* Set the stack pointer to application's MSP */
__asm volatile ("msr msp, %0" : : "r" (app_msp));
// /* Memory barrier */
// __asm volatile ("dsb");
// __asm volatile ("isb");
/* Jump to application's Reset_Handler */
app_reset_handler();
/* Should never reach here */
while(1)
{
/* Infinite loop */
}
}