Update README

Document resources and fix some outdated information.
This commit is contained in:
Ralf Schlatterbeck 2017-08-22 21:09:46 +02:00
parent cc48b88713
commit 12ee7b7e39

View file

@ -3,12 +3,114 @@ OTA Update
========== ==========
OTA stands for "Over the Air". OTA update is used to flash a new 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 firmware to a device over the air. This documents (some of) the
requirements for OTA. requirements for OTA and how to use the current prototype
implementation.
For the impatient
=================
First see the Security note below.
Then, if you've decided you want to try this: This is experimental code,
use at your own risk.
OK, how to run this:
There is now a new make variable that determines which image (the one
for the upper or the one for the lower half of flash memory) is to be
built. Set ::
BOOTLOADER_PARTITION=0
for building the first partition (the default) or set it to 1 for
building the second one.
There are now two ELF files, ``ota.osd-merkur-256.0`` and
``ota.osd-merkur-256.1``. From each of these two .hex files can be
generated (we're describing only the files for the first image, the
filenames of the second image are determined by replacing '0' with '1'
in the following):
- ota.osd-merkur-256.0.hex is the file used for OTA update
- ota.osd-merkur-256.0-combined.hex is the file used for uploading via
the bootloader. This file has an additional section that contains a
copy of the irq-vector table (see below for further details). This is
only necessary if you're using the latest bootloader.
To upload an image via OTA:
- Create the ``.hex`` file with::
make TARGET=osd-merkur-256 BOOTLOADER_PARTITION=1 ota.osd-merkur-256.0.hex
- Generate the ``.bin`` file with::
./ota_uploader.py x ota.osd-merkur-256.0.hex > ota.osd-merkur-256.0.bin
Note that the ``ota_uploader.py`` tool is intended to turn into a
full-fledged upgrade tool. This is work in progress. The first
parameter will be the destination IP-Address in the future and is
currently ignored.
- Upload this image to the ``/update`` resource, either via the firefox
copper plugin or via the commandline::
coap-client -t application/octet-stream -f ota.osd-merkur-256.1.bin
-m put -b 64 'coap://[2001:db8:c001:f00d:221:2eff:ff00:5dd4]/update'
Be sure to specify the type ``application/octet-stream`` if you are
uploading via copper. Also make sure you replace the IP address above
with the IP address of your board to be upgraded.
CoAP-Resources, Image Management
++++++++++++++++++++++++++++++++
The bootloader now keeps a directory of the images. In this directory we
keep the following information which can be retrieved or set via CoAP
resources:
- partition-ok: A flag per partition that indicates if this partition
has ever been successfully booted. This flag can only be set for a
partition that is currently running. Via CoAP this is set via the
``/part_ok`` URI. In addition to the URI, a query-parameter indicating
the partition has to be specified, e.g., ``/part_ok?part=1``.
Note that when a partition is flashed via the bootloader (and not via
OTA) this flag is *not* set. So if later a new partition is loaded via
OTA and the old partition never was marked OK, the old partition has
to be rebooted before it can be made the default partition again.
The part_ok resource can currently not be queried via a GET request.
- boot-default: The default boot partition, can be changed if the new
default partition has the partition-ok flag set. The CoAP resource is
``/boot_default`` and it can be queried via a GET request and set via
a PUT request, the parameter to the PUT request is the partition
number.
- boot-next: A temporary flag that can be set on a partition to boot it
just the next time. If booting fails the system will automatically
boot the boot-default partition next time. This is automatically set
after uploading an image. The CoAP resource is ``boot_next``. It can
also be changed via the resource similar to ``/boot_default`` but
without any constraints.
Additional CoAP resources exist to query the bootloader for parameters
that are not kept in the directory:
- ``/part_count``: Currently always 2, in the future the bootloader may
support more than two partitions
- ``/part_size``: The size of one partition, all partitions are equal in
size.
- ``/part_start``: This resource needs an additional query-parameter
indicating the partition number, e.g., ``/part_start?part=1`` and
returns the partition start address in flash.
- ``active_part``: The partition that is currently booted.
Security Security
======== ========
This is experimental code. There is currently no security, everybody (!)
can update your node. So use this only in experimental setups for now
until client-side DTLS authentication is available.
Position Independent Code Position Independent Code
========================= =========================
@ -37,29 +139,33 @@ are accessed and the bootloader then only relocates the addresses in the
jump-table. jump-table.
The first implementation will use two images (one for upper-, one for The first implementation will use two images (one for upper-, one for
lower half). lower half). We may decide to add on-the-fly relocation or we may always
ship two images (e.g. in a .zip file) and create a flash tool that
determines the correct image from the system to be updated.
Memory Layout Memory Layout
============= =============
The following table might have changed when you read this. See the
``stk500boot_atmega256rfr2`` bootloader on github, in particular the
file ``flash_layout.h`` for details.
+--------------------------------------+ +--------------------------------------+
| 3E000-3FFFF Bootloader | | 3E000-3FFFF Bootloader |
+--------------------------------------+ +--------------------------------------+
| 3DE00-3DFFF Flash image directory | | 3DE00-3DFFF Flash image directory |
+--------------------------------------+ +--------------------------------------+
| 3DC00-3DDFF IRQVec copy upper image | | 3D600-3DDFF IRQVec copy upper image |
+--------------------------------------+ +--------------------------------------+
| 1F100-3DBFF | | 1EF00-3D5FF |
| Upper Image (w/o first two pages) | | Upper Image |
| | | |
| | | |
+--------------------------------------+ +--------------------------------------+
| 1EF00-1F0FF IRQVec upper image | | 1E700-1EEFF IRQVec copy lower image |
+--------------------------------------+ +--------------------------------------+
| 1ED00-1EEFF IRQVec copy lower image | | 00000-1E6FF |
+--------------------------------------+ | Lower Image |
| 00200-1ECFF |
| Lower Image (w/o first two pages) |
| | | |
| | | |
+--------------------------------------+ +--------------------------------------+
@ -68,14 +174,19 @@ Memory Layout
We have two identical images. Each image contains the IRQ vectors (and 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 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 these pages (currently 8 pages as of this writing) is kept after the
the IRQ vectors are fixed at address 00000 in this processor image. The reason is that the IRQ vectors are fixed at address 00000 in
architecture. So for running an image we need to copy the irq-vectors to this processor architecture. In addition the compiler creates jumptables
(so-called trampoline code) to reach functions everywhere in memory via
a near call. 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 fixed location (and therefore we keep a backup to be able to restore
the original image at that location). the original image at that location).
We use the irq vectors in the bootloader to determine the
currently-running image: The first vector at position 0 is a jump to the
start of our program. From the address of this jump we can find out
which image is currently running.
Note that in the table above an image as generated by the compiler 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 consists of the IRQ vectors in the first pages plus the rest of the code
first and 1EF00-1F0FF for the second image) plus the rest of the code
for that image. for that image.