Hello,
I am having issue with my Jump to boot function. I have a bootloader located in flash code at address 0x00000000 to 0x00010000 and an application in flash code at address 0x00010000 to 0x00040000.
Here are my linker files
Boot
/* Specify the memory areas */
MEMORY
{
/* Flash */
m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x00000400
m_flash_config (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010
m_text (RX) : ORIGIN = 0x00000410, LENGTH = 0x0f000 - 0x410
/* programe_flash*/
m_boot_version (RWX) : ORIGIN = 0x0000f000, LENGTH = 0x00000040 /*version number */
/* SRAM_L */
m_data (RW) : ORIGIN = 0x1FFFC000, LENGTH = 0x00004000
/* SRAM_U */
m_data_2 (RW) : ORIGIN = 0x20000000, LENGTH = 0x00003000
}
Application
/* Specify the memory areas */
MEMORY
{
/* Flash */
m_interrupts (RXW) : ORIGIN = 0x00010000, LENGTH = 0x00000400
m_flash_config (RXW) : ORIGIN = 0x00010400, LENGTH = 0x00000010
m_text (RXW) : ORIGIN = 0x00010410, LENGTH = 0x00030000 - 0x410
/* programe_flash*/
ccp_code_sav (RWX) : ORIGIN = 0x00030000, LENGTH = 0x00002000 /*8k*/
ccp_code_tem (RWX) : ORIGIN = 0x00032000, LENGTH = 0x00002000 /*8k*/
m_app_version (RWX) : ORIGIN = 0x00034000, LENGTH = 0x00001000 /*version number 4k*/
ROM_writeflas (RWX) : ORIGIN = 0x00035000, LENGTH = 0x00001000 /* ROM_writeflash 4k*/
/* data_flash */
app_programe_dat (RW) : ORIGIN = 0x10000000, LENGTH = 0x00001000 /*8k*/
eeprom_dat (RW) : ORIGIN = 0x10002000, LENGTH = 0x00002000 /*8k*/
/* SRAM_L */
m_data (RW) : ORIGIN = 0x1FFFC000, LENGTH = 0X00001000 /*4K place have initialize global variable that not include 0*/
m_data_2 (RW) : ORIGIN = 0x1FFFD000, LENGTH = 0x00003000 /*12k heap and stack size*/
/* SRAM_U */
m_data_RAM0 (RW) : ORIGIN = 0X20000000, LENGTH = 0x00001000/* 4k gloab */
m_data_RAM1 (RW) : ORIGIN = 0x20001000, LENGTH = 0x00001000/* 4k app data*/
m_data_RAM3 (RW) : ORIGIN = 0x20002000, LENGTH = 0x00001000/* 4k CCP data*/
}
There is just an offset of 0x10000. And here is my code to jump to application :
void JumpToExecute(uint32_t SP, uint32_t Startup)
{
/* Mask interrupt */
DISABLE_INTERRUPTS()
__asm__("mov r0, #0x00");
__asm__("msr control, r0"); // nPRIV = 0
/* Set up Main and Process stack pointer (MSP, PSP)*/
__asm("ldr r0, =0x00010000");
__asm("msr msp, r0");
__asm("msr psp, r0");
/* Relocate Vector table */
S32_SCB->VTOR = (uint32_t)APP_IMAGE_START;// & S32_SCB_VTOR_TBLOFF_MASK;
/* Set program counter (PC) to the start of the reset handler */
__asm("ldr r1, =0x00010004");
__asm("mov pc, r1");
}
When i set a breakpoint on the last instruction i.e __asm("mov pc, r1"); it jump to unknown code:
But as you can see in the register view, i can see that sp is set to 0x10000 and pc is set to 0x10004.
I tried different addresses for setting PC, as 0x10410 but it doesn't jump at my start code application, i know it since i have set a Debug flag as in this article and a breakpoint with a condition on r11, and it never reach my flag..
Any ideas of what can be wrong ?
Best regards
解決済! 解決策の投稿を見る。
I don't even see a valid stack address in the whole memory range you posted.
There should be something like 0xXXXXXX20 (SRAM_U) or 0xXXXXXX1F (SRAM_L), depending on the location of the stack.
There is clearly something wrong with the bootloader.
Check the SREC file of the application and see how it is being programmed by the bootloader.
BR, Daniel
Hello Daniel,
Thank you for your answer. When i look to your example, you do
/* Set up stack pointer */
__asm("msr msp, r0");
__asm("msr psp, r0");
/* Relocate vector table */
S32_SCB->VTOR = (uint32_t)APP_START_ADDRESS;
/* Jump to application PC (r1) */
__asm("mov pc, r1");
But in my case r0 and r1 are set to zero all the time. so when i load the values in SP and PC they are zero aswell.
Is it normal ?
Best regards,
Hello @BriceC,
In the demo, the code is placed within a function that takes two arguments.
So, at the start of the function, the first argument is placed in R0 and the second argument in R1.
BR, Daniel
Hi,
Ok i see how r0 and r1 are set, now they have the value in memory at address 0x10000 and 0x10004, but it seems that my userSP and Startup are erased, since they are equal to 0xFFFFFFFF. Which are the values at theses addresses, but not what i want.
Best regards,
Can you open 0x10000 - 0x10004 in the Memory view, not Disassembly.
Thanks
As you can see values at 0x10000 and 0x10004 are 0xFFFFFFFF
I don't even see a valid stack address in the whole memory range you posted.
There should be something like 0xXXXXXX20 (SRAM_U) or 0xXXXXXX1F (SRAM_L), depending on the location of the stack.
There is clearly something wrong with the bootloader.
Check the SREC file of the application and see how it is being programmed by the bootloader.
BR, Daniel
Hi Daniel,
I found that a part of the SREC was not correctly flashed because of a missing equal in
if(address>=APP_IMAGE_START)
Now my code is jumping correctly and i can see my debug flag, thank you for your help !
Hello @BriceC,
Just regarding the jump.
The SP can't be 0x10000, because the stack is in the SRAM.
Refer to AN12218SW
https://www.nxp.com/docs/en/application-note-software/AN12218SW.zip
Bootloader_Software\S32K148_bootloader\src\main.c
R0 register should be loaded with *((uint32_t*)0x10000, that means the value (an SRAM address) at 0x10000.
Similarly for 0x10004.
Regards,
Daniel