In the previous article, UpdateHub: Sending OTA Updates Using the Yocto Project, we explored how to integrate the UpdateHub to your Yocto Project-based image. In this article, we will see how to use the UpdateHub with a Zephyr Project-based application.
Requirements and Dependencies
This tutorial was run on a Debian/Ubuntu-based operating system, and the application on the
NXP device FRDM-K64F (Freedom Development Platform for Kinetis® K64) with the
Zephyr Project version 1.14.
You can use other operating systems and other devices (remembering that devices must have a functional connection to the Internet), you just need to adjust the settings for your device and build environment.
This tutorial was designed for you to perform each step on the same terminal, so it will contain all the necessary environment settings. Therefore, it is not necessary to open multiple terminals, just use the terminal in the
~/ directory to execute the proposed commands.
To perform this tutorial it is necessary to install on your computer some dependencies such as Zephyr Project and the
Obtaining the Zephyr Project it is very simple, below we will show you how to do the installation and configuration, for this just follow the commands. The rest of the tutorial considers that the Zephyr Project directory will be in
First we will install
west on your system, with the following command:
pip3 install --user west
UpdateHub is currently close to being integrated into the official Zephyr Project repository, as can be seen in this Pull Request. For now we can use UpdateHub through our UpdateHub/Zephyr project
fork which maintains a backport of the patches to the 1.14 version. You can download our
fork with the following command:
west init -m https://github.com/UpdateHub/zephyr
After downloading the repository we need to install the Zephyr Project dependencies:
pip3 install --user -r ~/zephyr/scripts/requirements.txt
In this step we will download the
zephyr-sdk through the command:
zephyr-sdk, just run the command below. One tip is to keep installing the
SDK in the default
Last step is the configuration of the build environment, with the following command:
You can see the getting start guide explaining its tools of Zephyr Project.
Next, we will prepare the MCUboot. MCUboot is a secure boot loader for 32-bit MCUs, in this tutorial we will use JuulLabs-OSS/MCUboot. For the rest of the tutorial the MCUboot directory will be found in
~/mcuboot. Just clone this repository on your computer.
git clone https://github.com/JuulLabs-OSS/mcuboot.git
After the repository is cloned, the MCUboot dependencies must be installed:
pip3 install --user -r ~/mcuboot/scripts/requirements.txt
Now we need to install the UpdateHub utilities (uhu). The
uhu is an interactive prompt and command line utility for managing update packages for the UpdateHub agent. Downloading
uhu is very simple, just run the following command:
pip3 install --user uhu
Finally we need to install the pyOCD which is an open source Python package for programming and debugging ARM Cortex-M microcontrollers, it will be used in this tutorial. To Install, type the following command:
pip3 install -U --user pyocd
Flashing MCUboot’s image at device
The first step to starting the application is to write the MCUboot image file to the device. This can be done in several ways, to make it easier we will use the west command. In the MCUboot directory, cloned on your computer, navigate to
~/mcuboot/boot/zephyr and edit the
prj.conf file, the
CONFIG_MULTITHREADING option from
y. After this change we can compile the image of MCUboot and write to the device, to do this simply execute the following commands on your terminal at home directory:
west build -s ~/mcuboot/boot/zephyr -d build-mcuboot -b frdm_k64f west flash -d build-mcuboot
After this command the device will already be running the MCUboot image.
Modes to run UpdateHub in the Zephyr Project
UpdateHub has two different update modes at Zephyr Project, one manual and the other automatic.
The manual mode allows the user to control the update flow, the user is in charge of defining in his application the moment he wishes to query for an update and, if one is to be performed.
The automatic mode, UpdateHub will start working in parallel with the application and will automatically query the server if there is any update available, within a predetermined time, with updates will automatically install and start the device.
The example application shows how to use both examples, but by default the application is set to use automatic mode, which makes it easier to search for updates. If you want to use the manual mode just make a change in the configuration file.
Starting the UpdateHub server
By default, the UpdateHub application is configured to start in the UpdateHub Cloud. This server has the option of using CoAPS/DTLS. In this tutorial we will use the open-source server, called Updatehub Community Edition (updatehub-ce).
You can use updatehub-ce to do your tests and run everything locally. The rest of the tutorial will be based on this server. To use updatehub-ce, just run the following command on a terminal:
docker run -it -p 8080:8080 \ -p 5683:5683/udp \ --rm updatehub/updatehub-ce:latest
Using this server you need to create your own
overaly-prj.conf option, navigate to the application example in
~/zephyr/samples/net/updatehub. Create the
overlay-prj.conf file, following the
overlay-prj.conf.example model, configuring the
CONFIG_UPDATEHUB_SERVER option with your local IP address, and the
CONFIG_UPDATEHUB_CE option must be enabled. The
CONFIG_UPDATEHUB_PRODUCT_UID settings can be kept the same as the overlay-prj.conf.example values.
Building UpdateHub application
In this step we will show you how to compile the UpdateHub application for the
fdrm_k64f device. You should be in the following directory
~/ and run the command below.
west build -b frdm_k64f -s ~/zephyr/samples/net/updatehub \ -d build-updatehub \ -- -DCONF_FILE="prj.conf overlay-prj.conf"
Signing the builded image
In order to maintain security for the user, the images must be signed with the same key defined at the MCUboot startup. If the image is not signed or the signature key is wrong, MCUboot does not let the image to be written to the device.
The command below creates an image file named
zephyr.signed.bin and saves it to the directory its current directory. This image will be recorded on the device later.
west sign -t imgtool --no-hex \ -d build-updatehub/ -- \ --key mcuboot/root-rsa-2048.pem \ --version 1.0.0+0 \ --pad
Flashing the signed image of the application on the device
zephyr.signed.bin file to your device, type the following command:
west flash -d build-updatehub --bin-file zephyr.signed.bin
Gerando a imagem de atualização
At this stage of the process you will create a signed image that will be used to update your device. In this case, we will sign the same binary previously created just by changing the version, from
2.0.0. To do this, simply execute the command below:
west sign -t imgtool --no-hex \ -d build-updatehub/ -- \ --key mcuboot/root-rsa-2048.pem \ --version 2.0.0+0 \ --pad
O this command creates an image file named
zephyr.signed.bin in its current directory.
Build your package using UpdateHub Utilities
Building a package using
uhu is very simple, the first step is to configure the
product-uid of the package (even defined in the configuration of the image in the overlay-prj.config file), add and set the
package mode, inform the image
version, add the
supported hardware, and finally, you must generate the package.
To perform all of the above steps simply use the following command:
uhu product use "e4d37cfe6ec48a2d069cc0bbb8b078677e9a0d8df3a027c4d8ea131130c4265f" && \ uhu package add zephyr.signed.bin -m zephyr && \ uhu package version 2.0.0 && \ uhu hardware add frdm_k64f && \ uhu package archive --output example.pkg
The above command creates a package file named
example.pkg and saves it to the current directory.
Adding the package to the server
Package created, we are now ready to add the package to updatehub-ce. Open your browser and type the server’s URL (for example <your-ip-address>: 8080), it will open a login page, by default login and password must be filled in by
admin, fill in the fields and press login.
After accessing the server, click the Package menu, then Upload Package, and browse to your computer for the
example.pkg package you created in the previous step.
Registering the device on the server and creating a Rollout
In order for us to update the device with the image we added in updatehub-ce it is necessary to create a Rollout. To create it first you need to register the device on the server. There are two ways to do this, the first is to wait for the application to perform automatically in the predefined period (if you are using the automatic UpdateHub application), in this example the timeout set is the one-minute intervals (as defined in the
overlay-prj.config file). The other way to register the device on the server is by typing the following command into the debug terminal of the device: (Probably the device will already be registered since we are using automatic server query mode).
Returning to your browser, where updatehub-ce is open, you can navigate to the Devices tab and you will notice that your device information will be there, so you can create a rollout.
Navigate to the Rollout tab, click Create Rollout and select the version of the package you added (2.0.0), and then click Create. It will open a screen with the details of the Rollout, and just below it has the status information of the rollout, initially the status will be as pending.
Updating the device
Now everything is ready to update the device with the image available on the server. The update can be performed in two different ways, automatically by the application or through the console shell.
This tutorial, as we said before, uses the automatic query mode, where the device makes a query to the server checking if it has any update, getting answer that there is an update to be performed, it will automatically start downloading and install the image, finally device. When the device boots with the new image it will automatically query the server for more updates, the server will return to the device that there are no more updates and the Rollout will be set to Updated.
You can choose the second update mode where you can manually query by typing in the debug terminal of the device the command:
The device will download, install the new image and at the end the message "Image flashed successfully, you can reboot now" will appear on the screen, so you can restart the device by executing the following command in the terminal device debugging:
kernel reboot warm
The device will boot to the new image and query the server if there is any other update, the server will return to the device that has no more updates and the Rollout will be set to Updated.