OTA update
Last updated
Last updated
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 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 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.
Code available .
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:
The top level directory that contains this script can contain one of two things:
Update directory: These should be named with a version number compatible
with the python LooseVersion versioning scheme
They should contain the entire file system of the end device for the
corresponding version number.
This file should be in the format of the appimg.bin
created by the Pycom
firmware build scripts.
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:
The manifest contains the following fields:
delete
: A list of paths to files which are no longer needed
firmware
: The URL and SHA1 hash of the firmware image
new
: the URL, path on end device and SHA1 hash of all new files
update
: the URL, path on end device and SHA1 hash of all files which
existed before but have changed.
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:
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.
Below is am example implementing the methodology previously explained in this tutorial to initiate an OTA update.
().
Firmware: These files should be named in the format firmare_VERSION.bin
, where VERSION is a a version number compatible with the python LooseVersion versioning scheme ().
A MicroPyton library for interfacing with the server described above is available .