Firmware updates

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

Firmware updates

1,090 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by jdurand on Thu Nov 01 20:07:47 MST 2012
I'm porting code over to an LPC1226 and am having trouble figuring out how to do it.  Up to this point all my LPC projects haven't needed field updates but now I'm getting to the products that require it.

On other processors I simply load an encrypted mirror of the update into a cheap external serial flash, then run an assembly routine in RAM that erases all the on-chip flash and copies the new update in.  This has worked well on several brands of processors for many years (since the 1990s).

Now I get to the LPC series where it appears that I can't erase sector 0. If there IS a way, please let me know (I need to have code running THIS weekend).

I have the assembly routing working perfectly up until it tries to erase all of flash.

I've been searching all over and find articles about boot-loaders to copy programs to RAM or load code in odd places.

ALL I want to do is be able to copy my image in just like I was loading it fresh with the SWD.

So, I either need to erase ALL of the flash or have a way to move my code up one sector and re-map the vectors (PIA!).

Is there an application note on how to do this (or better, just tell LPCXpresso to handle it)?

ISP is NOT an option.  Not secure, we would never allow that. Also each product checks if an update is authorized (maybe you didn't pay for that version of code, you have code for the wrong product, etc.).

Once I get this working, it would be nice to know why the SWD/ISP can erase sector zero but IAP can't.  Since I can erase the rest of the part it seems pointless to lock one sector.

I'm off to continue researching this.
Labels (1)
0 Kudos
7 Replies

940 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rama krishna deekshitulu on Tue Feb 23 05:13:36 MST 2016
I would like to clarify my current situation,my code is split into two parts. The boot loader flashes an OTA upgrade using IAP and then jumps to the newly flashed code. My issue starts at this point where jumping to the new code sector using assembly to load the appropriate registers (SP & PC) with address to the values at the new application SP and PC locations.

New application code without SysTick runs fine and works normal but code that includes it tends to freeze.Do i need to do something specific to use SysTick timer with the secondary boot loader.

Does the application code need a specific sequence of code to use SysTick after jumping from bootloader or is this something that needs to be done before jumping to application in the bootloader.
0 Kudos

940 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by jdurand on Mon May 26 09:44:23 MST 2014
Just as a follow-up:  I've got security working well in various parts that we use (M0 and M3 cores).  On boot my code determines if it's a RELEASE version, maybe the serial number has been set or something like that.  If so, then it checks the CRP_WORD.  If it's == -1, then I overwrite it with CRP2.  In cores where you can only write pages, I copy 256 bytes to a buffer, overwrite the CRP_WORD in the buffer, then write it all back without doing an erase first.  Only works for changing ones to zeros.

Elsewhere in my code, if there's some hidden operation such as two switches shorted together and a certain pattern on others, then the code erases all sectors to allow reprogramming.
0 Kudos

940 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by jdurand on Tue Nov 06 17:27:22 MST 2012
Well, after lots of hassle it turns out I CAN erase sector 0 from IAP, so the Secondary Bootloader app note as well as the U10441 manual are both wrong or very not clear.

I haven't tried JUST erasing sector 0, but telling it to erase sectors 0-17 works just fine.

I'm guessing originally I had some item wrong and when I checked the manual and saw the note and then found the app note I gave up trying to erase sector 0.

Wish I'd found that before researching and writing the reflector code, but now I know how the vectors work and the linker scrips in way more detail than I wanted to know.
0 Kudos

940 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by jdurand on Sun Nov 04 18:25:11 MST 2012
Got the reflector working, WOW that was a pain.

If I load the program in with the Red Probe+ then both the boot sector and the main program load.

Once that's loaded, my encrypted firmware updates can be loaded in.

I wrote this generic so I won't need to change it for other projects.

I haven't tried setting the CRP yet, I wonder if the SWD reboots the processor after burning the flash but before verifying it?  If it does, that could be a problem.

I just downloaded FlashMagic, have to find a Windows system to run it on and do a test.  The ONLY thing I want it for is to recover from a failed flash update, but they're so seldom that it might be easier to just toss the chip and replace it with a new one.
0 Kudos

940 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by jdurand on Sat Nov 03 18:42:26 MST 2012
After reading bunches of app-notes that have me off editing linker scripts, etc. I figured out a way to wedge my code in to make a boot loader.

The following isn't the real code, it's just my testing to see if this will work.

>>> First, make a hole at the beginning of RAM to relocate the vector table.  I may not bother with this since I can just redirect each individual vector (painful, but it saves 256 bytes of RAM, not sure which is worse).

__attribute__((section(".bss.$RESERVED")))
int const TableReserve[] = {// save space for relocated vector table
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0
};


>>>> next, insert my vector table ahead of the program's vector table.  Where there's 0x1234 will actually be the hex data for the assembly instructions to either remap the vector table to RAM or a long list of redirects for every bloody vector.  

After that will be more padding to push the program's vector table to address 0x0000 1000 which is the start of sector 1 in the FLASH.

__attribute__ ((section(".isr_vector")))
int const BootVectors[] = {
(int)&_vStackTop,    // The initial stack pointer
    0x100,                              // The reset handler
0,0,0,0,0,0,// all null vectors
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0x1234// boot routine
};



Once all this is done, I can get back to useful coding since I have to ship this product THIS COMING WEEK!
0 Kudos

940 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by jdurand on Fri Nov 02 11:15:51 MST 2012
I see what I have to do (please let me know if something is missing):

Move the code start address to under TARGET SETTINGS 0x1000 and reduce the FLASH size by 0x1000

Move the RAM start address up to 0x10000200 since the VTOR is read-only (be nice to just remap to 0x1000) and reduce the RAM size by 0x200. 

Copy the real vector table from 0x1000 to RAM at 0x10000000.

Change the SYSMEMREMAP register to 0x1.

Branch to the RESET vector at 0x10000004 (and now done with "boot" code).

Now I have to somehow get this reflector code linked into to my programs and remember to change the TARGET settings for everything.  It almost sounds like I'm supposed to edit a copy of cr_section_macros.h, but that's in the main library and I don't touch library files (and neither does anyone who's worked for me). I guess I have to turn off automatic linker scripts and edit them.

I guess at this point I might as well use CRP2 since there's no really useful CRP mode (allow only ERASE_ALL SWD >OR< ISP would be very useful). At least it seems I can do a full erase with it if I can get serial data onto the UART0 pins.

Regarding ISP, since I've never used it, the P command says sector 0 can not be prepared for write/erase.  The E command says you can erase all sectors including 0 with it.  So...assuming CRP2, how do I use ISP to zap the entire part to blank so I can plug the SWD back in?

If I'd known the M0 parts were going to be this much of a pain (for no good reason that I can see), I would have never designed them in.  Overall I lose 4.5K of FLASH and 0.5k of RAM (and a couple of days work).
0 Kudos

940 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by jdurand on Thu Nov 01 21:17:16 MST 2012
Until I find a way to use the first 4k for something useful, I'm thinking I have the reset vector go to a short assembly routine to move the vector table to 0x1000.

Of course this kills any possibility of me changing the CRP word in the field in case someone crashes the firmware update (we do this on the other brand parts).

So, I'll be using less than a dozen bytes of the first sector.  :(
0 Kudos