Hi,
I am working on a bootloader in which all the steps are done but while jumping from boot to app there is an issue.
I am using the below mentioned boot to application jump code.
void goto_application(void)
{
void (*entry)(void);
uint32_t pc, sp;
INT_SYS_DisableIRQGlobal();
S32_SCB->VTOR=(uint32_t)(0xa000);
sp = *((volatile uint32_t*)0xa000);
__asm("ldr r0, =0xa000");
pc = *((volatile uint32_t *)(0xa000 + 4));
entry = (void (*)(void))pc;
entry();
}
The application base address is 0xA000.
I added the breakpoint in the code to check the register values are getting properly updated or not. And when the breakpoint hit the entry() in the code the register values got updated as you can see in the below screenshot.
But after entry() , program counter is jumped to 0xA33A location instead of 0xA004(pc value is given in the above code). Below screenshot refers to this point.
And also the application code is divided into 3 blocks.
1st block address starts from 0xA000 to 0xA2E5
2nd block address starts from 0xA400 to 0xA40F and
3rd block address starts from 0xA480 to 0x1FFFF.
Program counter is locating to the address which doesn't come in all 3 blocks .
So, could someone help me in fixing the issue with proper solution.
If working code is provided for boot to application jump would be highly appreciated.
Controller: MCU-S32K116
IDE-S32 DESIGN STUDIOS
COMPILER-IAR
Regards,
Ramsai
解決済! 解決策の投稿を見る。
Another idea - what does happen when you put a breakpoint at the entry point? Does it stop there? I'm wondering if you stepped over C level instruction or if you performed asm step. I believe it should work if asm step is used. If it works, you can load elf file of your application to have better understanding what happened.
Regards,
Lukas
Hi Lukas,
Thanks for your quick response.
Yes, when I tested with my previously mentioned bootloader to application code the r5 value is not getting updated. I tried in many ways but I couldn't able to make the r5 value matching with value present in 0xA004 address.
So, could you able to send the sample code of bootloader to application jump of s32k116 controller.
Regards,
Ramsai.
Hi Ramsai,
this is working code from AN12218:
/* Start address for the application received by the bootloader
* application vector table should start at this address
* */
#define APP_START_ADDRESS 0x1000
/* Check if a valid application is loaded and jump to it */
JumpToUserApplication(*((uint32_t*)APP_START_ADDRESS), *((uint32_t*)(APP_START_ADDRESS + 4)));
/**
* Used to jump to the entry point of the user application
* The Vector table of the user application must be located at 0x1000
*
* */
void JumpToUserApplication( unsigned int userSP, unsigned int userStartup)
{
/* Check if Entry address is erased and return if erased */
if(userSP == 0xFFFFFFFF){
return;
}
/* 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");
}
Regards,
Lukas
Hi Lukas,
I tried with the given working code shared by you. But even after implementing the same in my code its not jumping to application.
Please find below screenshots captured while debugging. These are for your reference.
Here in below screenshot APP_START_ADDRESS is 0xA000.
Kindly help me in identifying and solving this issue.
Regards,
Ramsai.
...and maybe one more thing - are all interrupts disabled before calling this function?
Hi Lukas,
All interrupts are disabled before calling of JumpToUserApplication() function.
Please find below screenshot.
Regards,
Ramsai.
Hi Ramsai,
I need to see a few previous steps. Could you take a screenshots:
- content of memory at 0xA000
- content of core registers r0 and r1 when the program jumps to JumpToUserApplication()
- content of core registers when it reaches __asm("mov pc, r1");
Thanks,
Lukas
Hi Lukas,
1. Please find below screenshot regarding content of memory at 0xA000.
2. Below screenshot will show you the content of core registers r0 and r1 when the program jumps to JumpToUserApplication().
3. Below screenshot shows you the values of all the registers when it reaches __asm("mov pc, r1");
For your info.
Regards,
Ramsai.
It works as expected.
At 0xA000, there's value 0x20003800 which is supposed to be loaded to stack pointer.
At 0xA004, there's value 0x0000BC69, so your entry point of application is at 0xBC68 (+1 is used for thumb instruction set).
On the last screenshot, I can see that the msp and psp are set to 0x20003800 which is correct. And it's going to move r1 (0xBC69) to program counter which is also correct.
I can see nothing wrong here.
Could you check in map file of your application if 0xBC68 is really your entry point? And could you also check if there's expected code at this address?
Regards,
Lukas
Hi Lukas,
Thanks for the confirmation.
When the debugger reaches the __asm("mov pc, r1"); r1 is getting updated with 0xBC69 but when I click on step-in after this step the code is keep on running so I clicked on suspend option.
When it is suspended it is showing that code is in 0xBA96 location and after this even though I keep on clicking on start button also it is showing as 0xBA96 location only.
Please find below screenshots regarding this.
Code is keep on running after __asm("mov pc, r1");
After suspending the code, pc is at 0xBA96.
I am also sharing you the values at these memory locations(0xBA96 and 0xBA69) and these are highlighted.
And also I am sharing you the screenshot of the map file at these locations.
Please look into this and do the needful.
Regards,
Ramsai.
Ok, it looks like there's valid opcode at entry point.
Could you send me a screenshot of these registers?
Thanks,
Lukas
Hi Lukas,
Please find below screenshot of the registers.
Regards,
Ramsai.
Another idea - what does happen when you put a breakpoint at the entry point? Does it stop there? I'm wondering if you stepped over C level instruction or if you performed asm step. I believe it should work if asm step is used. If it works, you can load elf file of your application to have better understanding what happened.
Regards,
Lukas
Hi Ramsai,
0xA004 is not entry point address and the code should not jump there.
There's reset vector at address 0xA004. And this reset vector then points to entry point of your application. Value in r5 register should be equal to value placed at 0xA004 and it should jump to this address. Could you check this? I can see in the screenshot that no application is programmed at this area.
Regards,
Lukas