My task is to update a targets (LPC1343) firmware using IAP. The only data connection available is a unidirectional (master -> target) serial line operating at 115,200 bit/sec. The application on the target contains a 'UART_IRQHandler()'. Its vector address is located in Flash as normal.
A - still to be written - IAP bootloader has to use the same uart and the same unidirectional data connection. But it cannot use the same 'UART_IRQHandler()' as addresses from 0x00000000 on should be overwritten by the IAP firmware update. So think of creating a seperate bootloader application and place it into sram. The application in flash should receive a special command from master, should jump to the bootloader in sram, bootloader should receive all bin packets of the firmware to ram and overwrite the application flash from 0x00000000 and at least jump to address 0x00000004 to get the new firmware running.
Some questions: Is this a good strategy? How to get the irq handlers of the bootloader activated instead of the application irq handlers?
Best regards, Juergen.
No boot loader in RAM - what happens if you lose power half-way through update.
Don't your processor supports remapping of the interrupt vector table, so you can have a bootloader (with ISR) in one part of the flash, and the normal application (with ISR) in a different part of the flash?
Ok, managed to build a second standalone Loader application to run in Flash. Configured 'Options for target', IROM1 (Default) 0x6000, 0x2000. Another questions: Where will the interrupt vector table of this application be located? How to get both apps into same target using UV4 (main application from 0x0000..0x5FF, loader from 0x6000..0x7FFF)? Seems that UV4 always erases the whole chip. Best regards, Juergen.
The LPC1343 has a boot built in whose sole purpose is to upgrade the user application. You may want to look into this and see if it does what you need (you set some GPIO lines and it automatically boots into the bootloader and allows updating flash through a Uart.)
With the Ulink2 programmer, UV4 will only erase the flash sectors that are written. Sectors seem to be 256 bytes in size. I have used an STM32 programming module (it was like $20) and it did erase all of flash. I don't use that any more...
The Bootloader should go at address 0 as you would always want to start with that. If there is no valid application image, you want to be able to load a new application image. This can happen if you erase the Application from the Bootloader, start to perform a download and some how power is lost. You will not lose the bootloader, but will not have a valid application. The bootloader can then jump to the application either right away if you do not want to do an upgrade or after loading the new image. You will remap the interrupt vectors to the base of the application image. I usually do 2 separate projects, 1 for the bootloader and 1 for the application. No need to program both most of the time...
I built two applications running at the target. Main application, sitting in lower flash (0x00000000..0x00005FFF) and loader application sitting in upper flash (0x00006000..0x00007FFF). Both use some SRAM (__attribute__ at...) to communicate. Both have a UART_IRQHandler() and a interrupt vector table.
Main app detects an 'update command', then tries to switch interrupt vector table from 0x00000000.. to 0x00006000.. and jumps to reset vector (0x00006004) of the loader app. So far everything works.
Problem at the moment: After switching and jumping, the loader UART_IRQHandler() seems not functional. Mainapp UART_IRQHandler() is no longer used (a breakpoint is not hit any longer). So interrupt vector switching has somewhat taken place, but...
Use this code: void (*user_code_entry)(void); unsigned *p;
__disable_irq(); SCB->VTOR = (0x00006000 & 0x1FFFFF80); p = (unsigned *)(0x00006000 + 4); loader_code_entry = (void *) *p; loader_code_entry();
Main application, sitting in lower flash (0x00000000..0x00005FFF) and loader application sitting in upper flash (0x00006000..0x00007FFF).
That's the wrong way round. The bootloader/flasher should always be at the CPU's initial reset location (0x00000000 here). That's the only way you stand any chance of surviving an interrupted update of the main application, e.g. by a power loss.
No matter what goes wrong, there always has to be some valid code to be executed immediately after coming out of hardware reset, and that's got to be your boot loader.
Thank you for this very fine hint! Will switch that, starting with loader, and after checksumming jumping to the main app. As a newbie at ARM/Cortex-M3: Can you estimate how much time is needed to checksum 24 kByte of code bytes on a LPC1343 running at 72 MHz? Best regards, Juergen.
That would obviously depend on algorithm used.
If you want a fancy algorithm, you obviously have to implement and test. And if all you want is to sum all the cells in that memory range, it takes you minutes to write the code and test.
View all questions in Keil forum