EmbeddedRelated.com
Forums
Memfault Beyond the Launch

Firmware updating - LPC2148

Started by Sutton Mehaffey October 3, 2011
I have put in a feature that takes an SD card with a .bin file on it,
uploads the file to an intermediate serial flash, then uploads from
serial flash to CPU RAM (in chunks) and then finally into CPU Flash. It
almost works, but not quite. My setup is:

I have a custom bootloader located at 0-0x4fff. At 0x4ff0-0x4fff are
bootloader parameters, such as version number and a valid code flag. At
0x5000-0x500f, I have a firmware version number and other firmware
related parameters. Starting at 0x5010 is the actual code. The size is
about 213K. Using Keil, the bootloader and app code can be loaded from
the JTAG, which works fine. The bootloader transfers execution to
0x5010 perfectly as uVision is set up to put the version code at 0x5000
and the app code at 0x5010.

For my automated firmware update, I have written some test routines
called 'Compare_SD_with_Serial_Flash', and
'Compare_Serial_Flash_with_CPU_Flash'.

My approach is:

1. The 16 byte firmware version and other parameters are concatenated
with the compiled app code (.axf) to produce a .bin file, using
fromElf.exe. The .bin file is copied to the SD card. In the field, the
.bin file will be emailed to the end user, who will put it on the SD
card and inserted into the embedded system (LPC2148).
2. The SD card .bin file is uploaded to a Serial Flash chip and
verified. Boot Flag set in External RAM that indicates new code is
available.
3. Watchdog timeout to invoke bootloader.
4. Bootloader sees that 'new code is available' and shows new version
number out of Serial Flash and total bytes of file
5. Asks user if he wants new code to be uploaded.
6. If no, then Boot flag reset and no code transfer.
7. If yes, then using CPU on-board SRAM, locations 0x40007000 -
0x40007fff, 1K chunks are uploaded from the Serial Flash and loaded into
the CPU Flash starting at location 0x5000. Once complete, the CPU Flash
is compared to the Serial Flash and verified. The Boot Flag is reset.
If code was not verified, then Boot Flag is not reset, which results in
continued tries of the upload upon reset.
8. Watchdog timeout to restart code.
9. Code Hangs and does not tranfer to 0x5010.
10. Load same app code using JTAG. Code now works. But Serial Flash no
longer matches CPU Flash.

Observations and other notes:

1. Serial Flash and SD card always match.
2. Serial Flash and CPU Flash always match even after system hangs, but
before any reload from JTAG. (I have a way to compare the code in the
bootloader, before the transfer to 0x5010).
3. After uploading same code thru JTAG, Serial Flash and CPU Flash match
from 0x5000-0x5fff, but always starting at 0x6000 no match.

4. before programming the code into CPU Flash, I erase sectors 5-23, so
that my bootloader in 0-4 is not touched, and so that the NXP bootloader
is not touched at 24-26.

Any initial thoughts on what's going on? Why is 0x6000 the magic
location of compare failure after uploading from the JTAG? It's a
sector boundary, so that's a little suspicious.

Sutton

--
Sutton Mehaffey
Lookout Portable Security
4040 Royal Dr.
Kennesaw, GA 30144
770-514-7999, 800-207-6269
Fax: 770-514-1285
http://www.lookoutportablesecurity.com
s...@lookoutportablesecurity.com

An Engineer's Guide to the LPC2100 Series

How do you handle the interrupt/restart vectors - when/where are they set up for the main code?

I use a similar system on 2129 and 2738, works OK.

I don't use a watchdog timeout to start my main code from the boot loader - I jump, (well, call via. a function pointer actually - the stack does not matter since the main app will soon set it up again anyway), directly from the boot code to the main app entry point, whereupon the main code copies its own vector table to RAM and remaps the vectors as part of its initialization. A watchdog timeout would then restart the main app - only a hard reset would make the bootloader run again.

You do seem to have another problem as well because of the '6000' issue, but I had to ask about the vectors..

Rgds,
Martin

Martin,

That might be the issue, but not sure. They are set up in the startup
code and are mapped starting at 5010, which is the Reset_Handler, which
is where my bootloader transfers control to. I struggle somewhat to
figure out the assembly code in the startup, but I remember way back
when I was beginning to start looking at this, someone on the forum
advised me to change the vector addresses to start at my transfer
point. I'm still looking.

Sutton

Sutton Mehaffey
Lookout Portable Security
4040 Royal Dr.
Kennesaw, GA 30144
770-514-7999, 800-207-6269
Fax: 770-514-1285
http://www.lookoutportablesecurity.com
s...@lookoutportablesecurity.com

On 10/3/2011 3:41 PM, mjames_doveridge wrote:
> How do you handle the interrupt/restart vectors - when/where are they
> set up for the main code?
>
> I use a similar system on 2129 and 2738, works OK.
>
> I don't use a watchdog timeout to start my main code from the boot
> loader - I jump, (well, call via. a function pointer actually - the
> stack does not matter since the main app will soon set it up again
> anyway), directly from the boot code to the main app entry point,
> whereupon the main code copies its own vector table to RAM and remaps
> the vectors as part of its initialization. A watchdog timeout would
> then restart the main app - only a hard reset would make the
> bootloader run again.
>
> You do seem to have another problem as well because of the '6000'
> issue, but I had to ask about the vectors..
>
> Rgds,
> Martin


By the way, my boot code does call a function pointer as well to call
the main app. However, since my boot code resides at 0, a watchdog
timer restarts the boot code, which is convenient in my case. I could
have just as well called the function pointer at the end of the upload,
but chose just to invoke the watchdog.

Sutton Mehaffey
Lookout Portable Security
4040 Royal Dr.
Kennesaw, GA 30144
770-514-7999, 800-207-6269
Fax: 770-514-1285
http://www.lookoutportablesecurity.com
s...@lookoutportablesecurity.com

On 10/3/2011 3:41 PM, mjames_doveridge wrote:
> How do you handle the interrupt/restart vectors - when/where are they
> set up for the main code?
>
> I use a similar system on 2129 and 2738, works OK.
>
> I don't use a watchdog timeout to start my main code from the boot
> loader - I jump, (well, call via. a function pointer actually - the
> stack does not matter since the main app will soon set it up again
> anyway), directly from the boot code to the main app entry point,
> whereupon the main code copies its own vector table to RAM and remaps
> the vectors as part of its initialization. A watchdog timeout would
> then restart the main app - only a hard reset would make the
> bootloader run again.
>
> You do seem to have another problem as well because of the '6000'
> issue, but I had to ask about the vectors..
>
> Rgds,
> Martin



Memfault Beyond the Launch