EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

Secondary bootloader - code won't execute

Started by ajellisuk March 3, 2009
Hi

I'm trying to implement a secondary bootloader. I have examined the
application note AN10711_2 provided on NXPs website, and I can
sucessfully copy an executable from external flash memory device to
the internal flash memory in the processor.

However I cannot get the code to execute. My code to try an execute
the user code from the bootloader is:

void (*user_code_entry)(void);
user_code_entry = (void (*)(void))0x18000; // address where user
code begine
user_code_entry(); // Start user code

When I use debbugger the program just steps over "user_code_entry()".

Dor you have any suggestions as to what could be going wrong?

Kind regards

Andrew Ellis

An Engineer's Guide to the LPC2100 Series

What does the assembly code look like ?
Did you step on assembly level or C level ?

--
42Bastian
On Tue, 3 Mar 2009, ajellisuk wrote:

> void (*user_code_entry)(void);
> user_code_entry = (void (*)(void))0x18000; // address where user
> code begine
> user_code_entry(); // Start user code

This:

#define FLASH_ADDRESS 0x10000
...
return ((int(*)(void)) FLASH_ADDRESS)();

... works for me. Generates:

----
return ((int(*)(void)) FLASH_ADDRESS)();

1e4: e3a03801 mov r3, #65536 ; 0x10000
1e8: e1a0e00f mov lr, pc
1ec: e1a0f003 mov pc, r3

// go off and run the secondary program, returns with its val in r0 ....

1f0: e1a04000 mov r4, r0
1f4: e1a00004 mov r0, r4
1f8: e8bd8010 pop {r4, pc}
----

(The assembly is a little convoluted 'cause I snipped some C out.)

-Kenny

--
Kenneth R. Crudup Sr. SW Engineer, Scott County Consulting, Los Angeles
O: 3630 S. Sepulveda Blvd. #138, L.A., CA 90034-6809 (888) 454-8181
Hi Bastian,

I stepped through the C code. I didn't think to step through the
assembly. I'll try that tomorrow.

Andrew
Hi,

I have stepped through the assembly code of my bootloader. The code branches to the main executable and steps through to a certain point then branches back to the bootloader. The steps are as follows:

My bootloader has the line in C:

return ((int(*)(void))USER_CODE_ADDRESS)(); // 0x18000

Which generates the following assembly:

MOV R0,#+98304
MOV LR,PC
BX R0
B ??main_1

When I hit the line "BX R0" the CPU jumps to my main executable as I would expect. I then hit this line:

BL 0x02A5F4

Which branches to this line:

LDR R12, [PC, #+0]

The contents of R12 is 0x4878. This address takes the CPU back into the bootloader code where it gets stuck in the following loop:

__exit:
STMDB SP!, {R122,LR}
BL __iar_sh_stdout_close ; 0x4618
MOV R1, #0x26
ORR R1, R1, #0x20000
MOV R0, #0x18
SWI 0x123456
B 0x004798

I have set up my linker to place the code at the location 0x18000. Is there a potential issue with absolute addressing? Is it possible to set up my compiler to use relative addressing? I'm Using IAR embedded workbench.

Can someone shed some light onto my problem please?

Thanks
Andrew
--- In l..., "ajellisuk" wrote:
>
> Hi,
>
> I have stepped through the assembly code of my bootloader. The code branches to the main executable and steps through to a certain point then branches back to the bootloader. The steps are as follows:
>
> My bootloader has the line in C:
>
> return ((int(*)(void))USER_CODE_ADDRESS)(); // 0x18000
>
> Which generates the following assembly:
>
> MOV R0,#+98304
> MOV LR,PC
> BX R0
> B ??main_1
>
> When I hit the line "BX R0" the CPU jumps to my main executable as I would expect. I then hit this line:
>
> BL 0x02A5F4
>
> Which branches to this line:
>
> LDR R12, [PC, #+0]
>
> The contents of R12 is 0x4878. This address takes the CPU back into the bootloader code where it gets stuck in the following loop:
>
> __exit:
> STMDB SP!, {R122,LR}
> BL __iar_sh_stdout_close ; 0x4618
> MOV R1, #0x26
> ORR R1, R1, #0x20000
> MOV R0, #0x18
> SWI 0x123456

Hmm.. have you set up your main app to copy/map interrupt vectors to RAM? If not, the first interrupt in your main code will just jump back to the boot code table!

I use a secondary boot loader to load main app updates from an SD card. My Rowley development environment has a #define to tell the compiler to generate the code to use RAM-mapped interrupt vectors. This works fine - the secondary boot loader jumps/calls to the main app, which then copies its own vectors to RAM and remaps the table there. The main app then runs up without problems, (mod. my bugs, of course).

When the reset button is pushed, the table gets remapped to flash and the bootloader runs again. It can look for update files on the SD card and either load them or just jump to the existing main app.

Rgds,
Martin
Hi,

I also faced similar kind of problem but i didnt remap the vectorTable to RAM rather I tried the following way,

In my case, i had UART2 configured as FIQ interrupt.

After jumping from Bootloader to application and when a UART2 - FIQ Interrupt occurs in the application, it jumps to reset location(obviously bootloader code) and got stuck over there and unable to handle FIQ Interrupts for application. (I believe this is what happening to you).

Make sure the Boot Loader uses only IRQ interrupts which will take the ISR address from VICVector Table (so?? no issues!!). Hence, in my case, the UART2 is configured as FIQ in application but IRQ in boot block and works fine. FIQ service handler will never occur in boot mode.

Also, the FIQ Service Handler is placed at the fixed address(Say e.g 0x20000) in the application, will get called when a FIQ exception occurs. This solves the issue of handling the FIQ in the application and the program behaves normally.
Any Comments?

Regards,
Ramdurai.B
On Wed, 4 Mar 2009, ajellisuk wrote:

> Is there a potential issue with absolute addressing?

Not that I've seen and I've done this for two seperate projects now.

-Kenny

--
Kenneth R. Crudup Sr. SW Engineer, Scott County Consulting, Los Angeles
O: 3630 S. Sepulveda Blvd. #138, L.A., CA 90034-6809 (888) 454-8181
Hi Ramdurai,

Thankyou for your reply. After spending a lot of time reading documentation I've not been able to work out how to place FIQ service handler at a fixed location. How did you do it?

Thanks

Andrew
Hi ,

You have to place the piece of code in Startup file as below,

FIQServiceHandler EQU 0x20000
...
...
FIQ_Addr DCD FIQ_Handler
...
...
FIQ_Handler B FIQServiceHandler

In the application,

#define FIQ_HANDLER_ADDRESS ".ARM.__at_0x20000"

#ifdef APPLICATION_CODE
__attribute__ ((section (FIQ_HANDLER_ADDRESS)))
void FIQServiceHandler(void)__irq
#else
...
..
#endif
Remember one thing, "FIQServiceHandler" in startup file and
"FIQ_HANDLER_ADDRESS" in app code should have same fixed address.

Hope this helps.

Regards,
Ramdurai.B

The 2024 Embedded Online Conference