OTA update

Overview

Pycom modules come with the ability to update the devices firmware, while it is still running, we call this an "over the air" (OTA) update. The pycom library provides several functions to achieve this. This example will demonstrate how you could potentially use this functionality to update deployed devices. The full source code of this example can be found here.

Method

Here we will describe one possible update methodology you could use that is implemented by this example.

Imagine you a smart metering company and you wish to roll out an update for your Pycom based smart meter. These meters usually send data back via LoRa. Unfortunately LoRa downlink messages have a very limited size and several hundred if not thousand would be required to upload a complete firmware image. To get around this you can have your devices sending their regular data via LoRa and when they receive a special command via a downlink message, the devices will connect to a WiFi network. It is unfeasible to ask customers to allow your device to connect to their home network so instead this network could be provided by a vehicle. This vehicle will travel around a certain geographic area in which the devices have been sent the special downlink message to initiate the update. The devices will look for the WiFi network being broadcast by the vehicle and connect. The devices will then connect to a server running on this WiFi network. This server (also shown in this example) will generate manifest files that instruct the device on what it should update, and where to get the update data from.

Server

This script runs a HTTP server on port 8000 that provisions over the air (OTA) update manifests in JSON format as well as serving the update content. This script should be run in a directory that contains every version of the end devices code, in the following structure:

This file should be in the format of the appimg.bin created by the Pycom

firmware build scripts.

How to use

Once the directory has been setup as described above you simply need to start this script using python3. Once started this script will run a HTTP server on port 8000 (this can be changed by changing the PORT variable). This server will serve all the files in directory as expected along with one additional special file, manifest.json. This file does not exist on the file system but is instead generated when requested and contains the required changes to bring the end device from its current version to the latest available version. You can see an example of this by pointing your web browser at:

http://127.0.0.1:8000/manifest.json?current_ver=1.0.0

The current_ver field at the end of the URL should be set to the current firmware version of the end device. The generated manifest will contain lists of which files are new, have changed or need to be deleted along with SHA1 hashes of the files. Below is an example of what such a manifest might look like:

version: The version number that this manifest will update the client to

previous_version: The version the client is currently on before applying

this update

Note: The version number of the files might not be the same as the firmware. The highest available version number, higher than the current client version is used for both firmware and files. This may differ between the two.

In order for the URL's to be properly formatted you are required to send a "host" header along with your HTTP get request e.g:

Client Library

A MicroPyton library for interfacing with the server described above is available here.

This library is split into two layers. The top level OTA class implements all the high level functionality such as parsing the JSON file, making back copies of files being updated incase the update fails, etc. The layer of the library is agnostic to your chosen transport method. Below this is the WiFiOTA class. This class implements the actual transport mechanism of how the device fetches the files and update manifest (via WiFi as the class name suggests). The reason for this split is so that the high level functionality can be reused regardless of what transport mechanism you end up using. This could be implemented on top of Bluetooth for example, or the sever changed from HTTP to FTP.

Although the above code is functional, it is provided only as an example of how an end user might implement a OTA update mechanism. It is not 100% feature complete e.g. even though it does backup previous versions of files, the roll back procedure is not implemented. This is left of the end user to do.

Example

Below is am example implementing the methodology previously explained in this tutorial to initiate an OTA update.

The example below will only work on a Pycom device with LoRa capabilities. If want to test it out on a device without LoRa functionality then simply comment out any code relating to LoRa. Leaving just the WiFiOTA initialisation and they ota.connect() and ota.update()