Update README
Document resources and fix some outdated information.
This commit is contained in:
parent
cc48b88713
commit
12ee7b7e39
|
@ -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.
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue