LPC1754 Execute from RAM to program Flash

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

LPC1754 Execute from RAM to program Flash

1,582 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by wdawson61 on Fri Aug 05 10:24:46 MST 2011
Hi all.  I need to implement the ability for an LPC1754 to update its entire 128k flash from code executing in RAM. I.e., the RAM code buffers the data from a peripheral and writes to flash using IAP.  We do not have access to UART0 so Can't just use ISP like we should.  I realize there will be a substantial risk of bricking the part, but need to proceed none the less. So, here is what I'm asking:

To build an image that can run from (a specific location in) RAM, do I just  modify my linker script to make all sections, text, bss, stack, load into one or more of the RAM sections?

Can an initialized data section still be used? 
i.e.
const int a=5;

Do I need to set any entry special point, etc?

Can I run this project under the debugger to test it?

Are there examples of this anywhere on the forum?

Many thanks in advance!

Wade.
0 Kudos
Reply
5 Replies

1,563 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by wdawson61 on Wed Aug 10 09:55:18 MST 2011
This sounds pretty reasonable to me.  The only potential issue I see with your version scheme is the lack of a way to rollback to a previous version.  I guess a user could "fake" the version number in a previous image, but doubtful that most will be able to pull that off - and, if there's a checksum... forget that.

Maybe instead of storing the current version number for comparison, you could store the version you want to update to.  The bootloader could find the image with the requested version info and update the firmware as per your procedure.  From that point forward the version number in eeprom will reflect the currently loaded firmware.  To rollback, the user app will need to either enumerate the firmware files on the update media and programatically determine the previous version or ask the user to pick it.  Once the version is selected, the update process does its thing performing the upgrade / downgrade of the firmware.

Just a thought...
0 Kudos
Reply

1,563 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Rob65 on Sat Aug 06 01:13:42 MST 2011

Quote: wdawson61
and the chances of bricking are greatly minimized by having the bootloader code in sectors untouched by the update process.  Am I missing something obvious?



With the debugging tip from Code Red (Thanks) I don't see why we cannot use the same process as used by the usb bootloader. We just have to replace the usb stack with the software to read from the USB flash drive (in your case) or the micro-SD card (in my case).

The (usb) bootloader checks for a valid user image in flash, if it is not there it will look (on flash drive/micro-SD) for the availability of a flashable image and write that one into flash.
The usb bootloader uses one input pin as ISP pin (not being P1.20 of course) so if there is a malfunctioning/incomplete user image in flash you can still update your device.
The bootloader itself is not overwritten and since it sits in the first flash blocks this will never leave your device bricked. Unless of course something strange happens - but that could always be the case.

As far as I remember the check for a valid user image comprises of a very small section of the flash being guarded with a checksum. So if something goes wrong during programming (use pulls the plug) there must be a way to flash the device.

I have some bytes left in a I2C EEPROM and was thinking of the following:

I reserve 2-3 bytes in the EEPROM to store a magic number and a 'user flash request'.
I store a version number in Flash, just behind the CRP magic number, so this can be read by the bootloader.
If the bootloader finds the 'user flash request' in EEPROM it checks the images on the USB flashdrive/SD card, only when the version number of the new images is newer than the current flash image it will erase and program the flash.
If the bootloader finds the 'valid user image' checksum plus the magic number in EEPROM then it starts executing the user image.

Before erasing the internal flash the bootloader erases the magic number in EEPROM and only writes it back after a full verification of the flash image. A fairly secure and nice way of doing this is by using an MD5 sum, also stored on the external medium.

Now it is up to the user application to decide wether or not we allow programming a new image. As an example, the user program detects that a usb flash drive is plugged in and it then detects there is a new image available. The application can now decide to program the 'user flash request' into the EEPROM and reset the device (using the watch dog or by just jumping to the ResetISR address in flash).

This gives me a good secure way of flashing the device without risk of bricking it; the user application can check the image (using the same MD5 sum) to make sure this is a valid image. I can now also interact with the user before I decide to flash the device, giving me the option to ask for e.g. an installation code or at least to place a warning on the LCD (or any other way of alerting the user) that the device is being flashed.

I think this is secure enough.
There is always a vary small chance that the correct magic number is found in the EEPROM without an invalid flash image but I tend to say this is almost impossible since the magic is only restored after a complete verification of the image.
If there somehow is a 'user flash request'  in EEPROM without a valid flash image on the external medium, the bootloader will detect this and start the current user image - this only introduces a delay in startup.

Hope this helps.

Regards,[INDENT]Rob
[/INDENT]
0 Kudos
Reply

1,563 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by wdawson61 on Fri Aug 05 15:41:52 MST 2011
Hi Rob.  I'm using the USB host port to read a usb flash drive.  I want to read new firmware from the usb flash drive, then program the LPC175x internal flash.  As I think about it, I may not need to run from ram at all.  We can probably opt for the larger LPC1756 or LPC1758 thereby having sufficient space for a bootloader / usb flash drive reader AND my 128k application code in flash.  I guess the IAP routines execute the actual wirte or erase instructions from the small RAM area it uses or boot ROM or in some way avoids executing from flash while erase or write operations are in process. 

This shouldn't actually be too bad afterall; and the chances of bricking are greatly minimized by having the bootloader code in sectors untouched by the update process.  Am I missing something obvious?
0 Kudos
Reply

1,563 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by CodeRedSupport on Fri Aug 05 12:33:12 MST 2011

Quote: Rob65

The only problem I now face is how to test and debug my code.
It seems that changing the start address of my programming section, as described in the readme of the usb_bootloader, is incompatible with the debug process of LPCXpresso.



Please see...

http://support.code-red-tech.com/CodeRedWiki/DebugThroughBootloader

Regards,
CodeRedSupport
0 Kudos
Reply

1,563 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Rob65 on Fri Aug 05 11:59:26 MST 2011
Hi Wade,

I am looking at a similar thing.
I have been investigating the USB bootloader for this.
A secondary bootloader (at 0x0000 in Flash) is then able to download and flash the remaining (if I remember correctly) 112 kB of the Flash.

Although this may not suite your needs, it does contain a short - sort of - tutorial on how to create your own linker scripts for this. You'll find this in the readme.txt in the RDB1768cmsis2_usb_bootloader project in the RDB1768cmsis2.zip file in the example folder of the LPCXpresso 4.0.5 tools (or other versions of the tools).

I am also thinking of a download option via a micro-SD card.
The trick is how to get your 'bootloader' into SRAM. If this bootloader is part of the Flash then we could as well use a solution similar to the usb_bootloader but it is also possible to first download the bootloader into SRAM, then start executing the code in SRAM and that code is responsible for downloading and programming the Flash.

I have been thinking about this for some time. The usb_bootloader way (reserving the first 16 kB in Flash for a separate bootloader) seems the simplest solution to implement.
The only problem I now face is how to test and debug my code.
It seems that changing the start address of my programming section, as described in the readme of the usb_bootloader, is incompatible with the debug process of LPCXpresso.

Another option might be to create a bootloader that is placed in the top Flash section.
The whole system as used with usb_bootloader is then reversed: the application is compiled (and programmed) as a normal application in Flash (from 0x00000 to 0x18000) and this application then calls the bootloader (starting at 0x18000) when needed.

An advantage of the original USB bootloader is that this can hardly brick your device. Advantage of the last option is that your application has full control over the entering of the bootloader (e.g. protection with a password).

The question is if it is OK for your application to get stuck with just 96 kB of Flash space when doing so.

Rob
0 Kudos
Reply