I'm using µVision 4.50.0.0 with Keil MCB1700 with LPC1768.
I wrote a secondary boot-loader, that reads srecord file from usb and writes that into flash starting 0x20000. The AN10866.pdf from NXP helped a lot.
The application itself is built with following changes: Target Options IROM1 Start 0x20000 Size 0x60000 Asm options Define NO_CRP.
The following code should start my application after successful update/validating the present firmware:
#define APPL_RUN_ADDR 0x00020000 __asm void boot_jump(U32 address) { LDR SP, [R0] LDR PC, [R0, #4] } void run_appl() { SCB->VTOR = APPL_RUN_ADDR & 0x1FFFF80; boot_jump(APPL_RUN_ADDR); }
This code snippet is copied from nxp's AN10866.pdf, too.
But the firmware doesn't start reliable. Where do I stuck?
APPL_RUN_ADDR is defined to 0x20000
at 0x20004 there's 00020229 (this is the Reset_Handler fro my application, which I checked in the map file).
Unfortunately I don't find the AN10866.zip example files, to see how nxp's bootloader was built exactly.
What else have I forgotten to do?
Thanks in advance Hubert
Digging even deeper into the assembly showed after reaching my main function
0x00021110 F7FEFFE9 BL.W 0x000200E6 0x00021114 2200 MOVS r2,#0x00 0x00021114 2200 MOVS r2,#0x00 0x00021116 4611 MOV r1,r2 0x00021118 F2AF0057 ADR.W r0,{pc}-0x53 ; @0x000210C5 0x0002111C F8DFC0C4 LDR.W r12,[pc,#196] ; @0x000211E4 0x00021120 DF00 SVC 0x00
executing the SVC 0x00 call results in the HardFaultHandler.
The C-code of that main look like
int main (void) { os_sys_init(init); while(1); }
I hope this gives some more hints about what I'm missing.
Thanks Hubert
Where do you remap your interrupt vectors for your new code into the proper interrupt offset prior to executing the os_sys_init(init) call? You need to go back and review how a system functions, I believe.
O.K.
Now I found the solution to start the application located at APPL_RUN_ADDR = 0x20000 reliably.
before changing the vector table the irq's have to be disabled in the bootloader.
__asm void boot_jump(U32 address) { LDR SP, [R0] LDR PC, [R0, #4] } void run_appl() { // void (*user_code_entry)(void); /* Change the Vector Table to the USER_FLASH_START in case the user application uses interrupts */ __disable_irq(); LPC_SC->PCONP = 0x001817BE; SCB->VTOR = APPL_RUN_ADDR & 0x1FFFF80; boot_jump(APPL_RUN_ADDR); }
and in the application the irq's have to be enabled again before calling os_sys_init()!!!
int main (void) { __enable_irq(); os_sys_init(init); /* Initialize RTX and start init */ }
The bootloader is compiled with IROM1 Start=0x0 Size = 0x20000
The application is compiled with IROM1 Start=0x20000 Size = 0x60000 and Asm Define = NO_CRP
Hubert
Note that this works _only_ because your specific controller starts up in privileged mode. This might not be the case using other controllers.