82 lines
3.2 KiB
ReStructuredText
82 lines
3.2 KiB
ReStructuredText
|
==========
|
||
|
OTA Update
|
||
|
==========
|
||
|
|
||
|
OTA stands for "Over the Air". OTA update is used to flash a new
|
||
|
firmware to a device over the air. This document (some of) the
|
||
|
requirements for OTA.
|
||
|
|
||
|
Security
|
||
|
========
|
||
|
|
||
|
Position Independent Code
|
||
|
=========================
|
||
|
|
||
|
The new contiki-osd-merkur-256 target should have enough memory for two
|
||
|
independent application images. An application image should include the
|
||
|
code for over-the-air update to ensure it can be upgraded in the field.
|
||
|
|
||
|
Upgrading an image means writing a new image into the other half of the
|
||
|
flash memory (the part which does not run the current image). Since an
|
||
|
image has internal addresses and is usually linked to fixed addresses we
|
||
|
have two options:
|
||
|
|
||
|
- Find a way to generate position independent code for the Atmel
|
||
|
microcontrollers so that an image can be used in the lower- or upper
|
||
|
half of flash memory
|
||
|
- Generate two images, one linked for the lower, one linked for the
|
||
|
upper half of flash memory.
|
||
|
|
||
|
It seems the GCC Atmel compiler cannot generate position independent
|
||
|
code. So we have to modify the first option to make it work: We can use
|
||
|
some magic during loading of an image to link it to the correct half of
|
||
|
flash-memory during loading. This can either mean full relocation of the
|
||
|
image (the same job that is normally done before runtime by the linker)
|
||
|
or offline-generation of a jump-table for all objects (functions) that
|
||
|
are accessed and the bootloader then only relocates the addresses in the
|
||
|
jump-table.
|
||
|
|
||
|
The first implementation will use two images (one for upper-, one for
|
||
|
lower half).
|
||
|
|
||
|
Memory Layout
|
||
|
=============
|
||
|
|
||
|
+--------------------------------------+
|
||
|
| 3E000-3FFFF Bootloader |
|
||
|
+--------------------------------------+
|
||
|
| 3DE00-3DFFF Flash image directory |
|
||
|
+--------------------------------------+
|
||
|
| 3DC00-3DDFF IRQVec copy upper image |
|
||
|
+--------------------------------------+
|
||
|
| 1F100-3DBFF |
|
||
|
| Upper Image (w/o first two pages) |
|
||
|
| |
|
||
|
| |
|
||
|
+--------------------------------------+
|
||
|
| 1EF00-1F0FF IRQVec upper image |
|
||
|
+--------------------------------------+
|
||
|
| 1ED00-1EEFF IRQVec copy lower image |
|
||
|
+--------------------------------------+
|
||
|
| 00200-1ECFF |
|
||
|
| Lower Image (w/o first two pages) |
|
||
|
| |
|
||
|
| |
|
||
|
+--------------------------------------+
|
||
|
| 00000-001FF IRQVec running image |
|
||
|
+--------------------------------------+
|
||
|
|
||
|
We have two identical images. Each image contains the IRQ vectors (and
|
||
|
some code after the vector table) in the lower two pages. A copy of
|
||
|
these two pages is kept in two pages after the image. The reason is that
|
||
|
the IRQ vectors are fixed at address 00000 in this processor
|
||
|
architecture. So for running an image we need to copy the irq-vectors to
|
||
|
the fixed location (and therefore we keep a backup to be able to restore
|
||
|
the original image at that location).
|
||
|
Note that in the table above an image as generated by the compiler
|
||
|
consists of the IRQ vectors in the first two pages (00000-001FF for the
|
||
|
first and 1EF00-1F0FF for the second image) plus the rest of the code
|
||
|
for that image.
|
||
|
|
||
|
|