Jump from bootloader to application

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Jump from bootloader to application

3,116 Views
juanabelaira
Contributor III

I'm getting a hard fault when jumping from my bootloader to the app. It's on an LPC1519 and the bootloader resides at 0x0000 - 0x1FFF, while the application starts at 0x2000. I'm using LPCXpresso.

I've seen this question asked and apparently answered somewhere else but none of the solutions proposed worked for me. Here is the code I use for the jump:

SCB->VTOR = (0x2000);
asm volatile("ldr r0, =0x2000");   // Code start address
asm volatile("ldr sp, [r0]");
asm volatile("ldr r0, [r0, #4]");
//asm volatile("add r0, r0, 1"); // tried this as I read address has to be odd for thumb
asm volatile("mov pc, r0");
//asm volatile ("bx r0");           // tried this as I read is not safe to load PC

If I debug it, everything goes fine until the PC load or BX, where it goes to the hard fault loop.

Anything can point the right direction?

Cheers

Edited: If I edit the application 'ld' file to have the main as entry point, as below, then it works, but I'd like to know what the difference makes skipping the ResetISR function (the bootloader ran it anyways).

/*ENTRY(ResetISR)*/
ENTRY(main)

7 Replies

2,055 Views
juanabelaira
Contributor III

Update:

I found that it all works if I comment out the function call  Board_SetupClocking()  in   Board_SystemInit, that is called by SystemInit, called by  ResetISR. This way I have the initialisation from Flash and the clock was already initialised by the SBL.

More precisely, the offending lines inside Board_SetupClocking are the call to Chip_SetupXtalClocking and the always dangerous while (!Chip_Clock_IsUSBPLLLocked()) {}. Just if anyone else stumbles on this.

Still wondering why an apparent repeated clock setup would cause a problem ?!?! 

Another bit of a worry is that this makes me to have two software frame versions, standalone with clock setup and bootloader-launched without. 

Also, I noticed there are some USB clock initialisation. My LPC1519 hasn't got USB. I'm not sure but I'm just assuming that initialisation has no effect for that MCU. 

0 Kudos
Reply

2,055 Views
salmansattar
Contributor II

Hello 

Maybe this is not write place to ask my question. sorry for that but how did you manage to load the bootload and application at the same time in different memory locations ? 

0 Kudos
Reply

2,055 Views
juanabelaira
Contributor III

That's at least a side-topic. Anyways, the question is direct and easy, I first flashed the application with offset, like writing data on flash, then I flashed the bootloader then when reset it runs and jumps to the app. Remember not to use the 'erase all flash' option. There are more elegant ways, like the one pointed above here by Carlos.

2,055 Views
Carlos_Mendoza
NXP Employee
NXP Employee

Hi Juan,

I don't think that is the correct fix, it will only work correctly if the debugger is attached. I would recommend you to use the LPC1700 secondary USB bootloader as reference:

http://cache.nxp.com/docs/en/application-note/AN10866.zip

This is the function used by the bootloader to jump to the application:

__asm void boot_jump( uint32_t address ){
   LDR SP, [R0]        ;Load new stack pointer address
   LDR PC, [R0, #4]    ;Load new program counter address
}

Have you tried debugging your application startup code and see if ts is another instruction inside this function causing the hardfault?


Hope it helps!

Best Regards,
Carlos Mendoza
Technical Support Engineer

0 Kudos
Reply

2,055 Views
juanabelaira
Contributor III

Thanks, Carlos. Could you tell me what difference makes your code:

   LDR SP, [R0]        ;Load new stack pointer address
   LDR PC, [R0, #4]    ;Load new program counter address

instead of mine? I see it functionally identical.

asm volatile("ldr sp, [r0]");
asm volatile("ldr r0, [r0, #4]");
asm volatile("mov pc, r0");

Yes, I first debug then ask. It crashes right after the PC register is loaded. I checked the r0 register has the right value beforehand (the ResetISR address). But in this case I don't think debugging helps as I have the application flashed and what I debug is the bootloader, so the debugger doesn't know anything about the application after the "mov pc". I wonder if there is a way of debugging two independent applications.

Facts so far are:

- The bootloader executes fine until it jumps to the ResetISR [seen with debugger]

- The bootloader does jump to the ResetISR [reason below]

- If at the beginning of the ResetISR function I call main, then it works, but I'm skipping the RAM initialisation

Because of the above, I think my problem is with the RAM initialisation, but I can't see why copying from flash to RAM causes a hang.

0 Kudos
Reply

2,055 Views
Carlos_Mendoza
NXP Employee
NXP Employee

Hi Juan,

 

Yes, they are functionally identical. There could also be a problem with the SystemInit function, I would recommend you to debug both the bootloader and the application by adding the following command to your debug Run Commands:
add-symbol-file filename address
As an example:

 

add-symbol-file C:\\Users\\b38285\\Documents\\MCUXpressoIDE_10.0.0_344\\workspace\\MK64FN1M0xxx12_Project_2\\Debug\\MK64FN1M0xxx12_Project_2.axf 0x80000

 

pastedImage_1.png

 

The address 0x80000 corresponds to the first flash section of the second project which was previously flashed to the MCU:

 

pastedImage_3.png


Hope it helps!

 

Best Regards,
Carlos Mendoza
Technical Support Engineer

2,055 Views
juanabelaira
Contributor III

Mmm, I'm using LPC Link2, not Jagger, so I can't find the equivalent for my environment

0 Kudos
Reply