osd-contiki/examples/osd/ota-update
Ralf Schlatterbeck ed638a5f5a Add genbackupisr
2017-08-19 21:05:39 +02:00
..
genbackupisr.py Add genbackupisr 2017-08-19 21:05:39 +02:00
Makefile First sketch of image uploader 2017-08-19 19:26:27 +02:00
ota.c First stab at OTA-update 2017-07-31 13:26:29 +02:00
ota_uploader.py First sketch of image uploader 2017-08-19 19:26:27 +02:00
project-conf.h First stab at OTA-update 2017-07-31 13:26:29 +02:00
README.rst First stab at OTA-update 2017-07-31 13:26:29 +02:00
res_bootloader.c First sketch of image uploader 2017-08-19 19:26:27 +02:00
res_upload_image.c First sketch of image uploader 2017-08-19 19:26:27 +02:00
sketch.pde First stab at OTA-update 2017-07-31 13:26:29 +02:00

==========
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.