| .. _updatehub_fota_sample: |
| |
| UpdateHub embedded Firmware Over-The-Air (FOTA) sample |
| ###################################################### |
| |
| Overview |
| ******** |
| |
| UpdateHub is an enterprise-grade solution which makes it simple to remotely |
| update all your embedded devices. It handles all aspects related to sending |
| Firmware Over-the-Air (FOTA) updates with maximum security and efficiency, |
| while you focus on adding value to your product. It is possible to read more |
| about at `docs.updatehub.io`_. |
| |
| This sample shows how to use UpdateHub in both a polling and manual update |
| mode. |
| |
| Polling mode runs automatically on a predefined period, probing the server |
| for updates and installing them without requiring user intervention. |
| |
| Manual mode requires the user to call the server probe and then, if there is |
| an available update, also requires the user to decide if it is appropriate to |
| update now or later. |
| |
| You can access the sample source code at |
| :zephyr_file:`samples/subsys/mgmt/updatehub/src/main.c`. |
| |
| Caveats |
| ******* |
| |
| * The Zephyr port of ``UpdateHub`` was initially developed to run on a |
| :ref:`Freedom-K64F <frdm_k64f>` kit using the ethernet connectivity. The |
| application should build and run for other platforms with same connectivity. |
| |
| * The sample provides overlay files to enable other technologies like WIFI, |
| modem, BLE IPSP, 802.15.4 or OpenThread. These technologies depends on |
| hardware resources and the correspondent overlay was designed to be generic |
| instead full optimized. |
| |
| * It is important understand that some wireless technologies may require a |
| gateway or some sort of border router. It is out of scope provide such |
| configuration in details. |
| |
| * The MCUboot bootloader is required for ``UpdateHub`` function properly. |
| Before chose a platform to test, make sure that SoC and board have support |
| to it. UpdateHub currently uses two slots to perform the upgrade. More |
| information about Device Firmware Upgrade subsystem and MCUboot can be found |
| in :ref:`mcuboot`. |
| |
| * ``UpdateHub`` acts like a service on Zephyr. It is heavily dependent on |
| Zephyr sub-systems and it uses CoAP over UDP. |
| |
| |
| Building and Running |
| ******************** |
| |
| The below steps describe how to build and run the ``UpdateHub`` sample in |
| Zephyr. Open a terminal ``terminal 1`` and navigate to your Zephyr project |
| directory. This allows to construct and run everything from a common place. |
| |
| .. code-block:: console |
| |
| ls |
| bootloader modules tools zephyr |
| |
| |
| Step 1: Build/Flash MCUboot |
| =========================== |
| |
| The MCUboot can be build following the instructions in the :ref:`mcuboot` |
| documentation page. Flash the resulting image file using west on |
| ``terminal 1``. |
| |
| .. zephyr-app-commands:: |
| :zephyr-app: bootloader/mcuboot/boot/zephyr |
| :board: frdm_k64f |
| :build-dir: mcuboot-frdm_k64f |
| :goals: build flash |
| |
| |
| Step 2: Start the UpdateHub Server |
| ================================== |
| |
| Step 2.1: UpdateHub-CE (Community Edition) |
| ------------------------------------------ |
| |
| The Zephyr sample application is configured by default to use the UpdateHub-CE |
| server edition. This version implies you need run your own server. The |
| UpdateHub-CE is distributed as a docker container and can be on your local |
| network or even installed on a service provider like Digital Ocean, Vultr etc. |
| To start using the UpdateHub-CE simple execute the docker command with the |
| following parameters on another terminal ``terminal 2``. |
| |
| .. code-block:: console |
| |
| docker run -it -p 8080:8080 -p 5683:5683/udp --rm |
| updatehub/updatehub-ce:latest |
| |
| Step 2.2: UpdateHub Cloud |
| ------------------------- |
| |
| The UpdateHub Cloud is an enterprise-grade solution. It provides almost same |
| resources than UpdateHub-CE with the DTLS as main diferential. For more |
| details on how to use the UpdateHub Cloud please refer to the documentation on |
| `updatehub.io`_. The UpdateHub Cloud has the option to use CoAPS/DTLS or not. |
| If you want to use the CoAPS/DTLS, simply add the ``overlay-dtls.conf`` when |
| building the sample. You can use the provided certificate for test this |
| example or create your own. The below procedure instruct how create a new |
| certificate using openssl on a Linux machine on terminal ``terminal 2``. |
| |
| .. code-block:: console |
| |
| openssl genrsa -out privkey.pem 512 |
| openssl req -new -x509 -key privkey.pem -out servercert.pem |
| |
| The ``servercert`` and ``privkey`` files must be embedded in the application |
| by ``certificates.h`` file. The following procedure can be used to generated |
| the required ``der`` files: |
| |
| .. code-block:: console |
| |
| openssl x509 -in servercert.pem -outform DER -out servercert.der |
| openssl pkcs8 -topk8 -inform PEM -outform DER -nocrypt -in privkey.pem |
| -out privkey.der |
| |
| |
| The ``der`` files should be placed on the sample source at certificates |
| directory. |
| |
| .. note:: |
| |
| When using UpdateHub Cloud server it is necessary update your own |
| ``overlay-prj.conf`` with option :kconfig:option:`CONFIG_UPDATEHUB_CE` equal ``n``. |
| |
| |
| Step 3: Configure UpdateHub Sample |
| ================================== |
| |
| The updatehub have several Kconfig options that are necessary configure to |
| make it work or tune communication. |
| |
| Set :kconfig:option:`CONFIG_UPDATEHUB_CE` select between UpdateHub edition. The ``y`` |
| value will select UpdateHub-CE otherwise ``n`` selects UpdateHub Cloud. |
| |
| Set :kconfig:option:`CONFIG_UPDATEHUB_SERVER` with your local IP address that runs the |
| UpdateHub-CE server edition. If your are using a service provider a DNS name |
| is a valid option too. This option is only valid when using UpdateHub-CE. |
| |
| Set :kconfig:option:`CONFIG_UPDATEHUB_POLL_INTERVAL` with the polling period of your |
| preference, remembering that the limit is between 0 and 43200 minutes |
| (30 days). The default value is 1440 minutes (24h). |
| |
| Set :kconfig:option:`CONFIG_UPDATEHUB_PRODUCT_UID` with your product ID. When using |
| UpdateHub-CE the valid is available at ``overlay-prj.conf.example`` file. |
| |
| |
| Step 4: Build UpdateHub App |
| =========================== |
| |
| In order to correctly build UpdateHub the overlay files must be use correctly. |
| More information about overlay files in :ref:`important-build-vars`. |
| |
| .. note:: |
| It is out of scope at this moment provide support for experimental |
| features. However, the configuration and use is similar to the start |
| point indicated on the experimental network interface. |
| |
| Step 4.1: Build for Ethernet |
| ---------------------------- |
| |
| The ethernet depends only from base configuration. |
| |
| .. zephyr-app-commands:: |
| :zephyr-app: zephyr/samples/subsys/mgmt/updatehub |
| :board: [ frdm_k64f | nucleo_f767zi ] |
| :build-dir: app |
| :gen-args: -DEXTRA_CONF_FILE=overlay-prj.conf |
| :goals: build |
| :compact: |
| |
| Step 4.2: Build for WiFi |
| ------------------------ |
| |
| For WiFi, it needs add ``overlay-wifi.conf``. Here a shield provides WiFi |
| connectivity using, for instance, arduino headers. See :ref:`module_esp_8266` |
| for details. |
| |
| .. zephyr-app-commands:: |
| :zephyr-app: zephyr/samples/subsys/mgmt/updatehub |
| :board: [ frdm_k64f | nrf52840dk_nrf52840 | nucleo_f767zi ] |
| :build-dir: app |
| :gen-args: -DEXTRA_CONF_FILE="overlay-wifi.conf;overlay-prj.conf" |
| :shield: esp_8266_arduino |
| :goals: build |
| :compact: |
| |
| .. note:: |
| The board disco_l475_iot1 is not supported. The es-WIFI driver currently |
| doesn't support UDP. |
| |
| Step 4.3: Build for Modem |
| ------------------------- |
| |
| Modem needs add ``overlay-modem.conf``. Now, a DTC overlay file is used to |
| configure the glue between the modem and an arduino headers. The modem config |
| uses PPP over GSM modem, see :ref:`gsm-modem-sample`. |
| |
| .. zephyr-app-commands:: |
| :zephyr-app: zephyr/samples/subsys/mgmt/updatehub |
| :board: [ frdm_k64f | nrf52840dk_nrf52840 | nucleo_f767zi ] |
| :build-dir: app |
| :gen-args: -DEXTRA_CONF_FILE="overlay-modem.conf;overlay-prj.conf" \ |
| -DDTC_OVERLAY_FILE=arduino.overlay |
| :goals: build |
| :compact: |
| |
| Step 4.4: Build for IEEE 802.15.4 [experimental] |
| ------------------------------------------------ |
| |
| For IEEE 802.15.4 needs add ``overlay-802154.conf``. This requires two nodes: |
| one will be the host and the second one will be the device under test. The |
| validation needs a Linux kernel >= 4.9 with all 6loWPAN support. The start |
| point is try reproduce the Zephyr :ref:`wpanusb-sample`. It is out of scope |
| at this moment provide support since it is experimental. The gateway was |
| tested with both native linux driver and ``atusb`` and with ``wpanusb`` sample. |
| |
| .. zephyr-app-commands:: |
| :zephyr-app: zephyr/samples/subsys/mgmt/updatehub |
| :board: nrf52840dk_nrf52840 |
| :build-dir: app |
| :gen-args: -DEXTRA_CONF_FILE="overlay-802154.conf;overlay-prj.conf" |
| :goals: build |
| :compact: |
| |
| .. zephyr-app-commands:: |
| :zephyr-app: zephyr/samples/subsys/mgmt/updatehub |
| :board: [ frdm_k64f | nucleo_f767zi ] |
| :build-dir: app |
| :gen-args: -DEXTRA_CONF_FILE="overlay-802154.conf;overlay-prj.conf" |
| :shield: atmel_rf2xx_arduino |
| :goals: build |
| :compact: |
| |
| Step 4.5: Build for BLE IPSP [experimental] |
| ------------------------------------------- |
| |
| The BLE IPSP needs ``overlay-ipsp.conf``. This may requires two nodes: |
| one will be the host and the second one will be the device under test. The |
| validation needs a Linux kernel >= 4.9 with all 6loWPAN support. In this |
| particular case the Bluetooth 6LoWPAN module is needed. The start point is try |
| reproduce the Zephyr :ref:`bluetooth-ipsp-sample`. It is out of scope |
| at this moment provide support since it is experimental. The gateway was |
| tested with native linux driver and an USB dongle. |
| |
| .. zephyr-app-commands:: |
| :zephyr-app: zephyr/samples/subsys/mgmt/updatehub |
| :board: nrf52840dk_nrf52840 |
| :build-dir: app |
| :gen-args: -DEXTRA_CONF_FILE="overlay-ipsp.conf;overlay-prj.conf" |
| :goals: build |
| :compact: |
| |
| Step 4.6: Build for OpenThread Network [experimental] |
| ----------------------------------------------------- |
| |
| The OpenThread requires the ``overlay-ot.conf``. It requires two nodes: |
| one will be the host NCP and the second one will be the device under test. The |
| validation needs a Linux kernel >= 4.9 with optional NAT-64 support. The |
| start point is try reproduce the `OpenThread Router`_. It is |
| out of scope at this moment provide support since it is experimental. The |
| gateway was tested using two boards with OpenThread 1.1.1 on NCP mode. |
| |
| .. zephyr-app-commands:: |
| :zephyr-app: zephyr/samples/subsys/mgmt/updatehub |
| :board: nrf52840dk_nrf52840 |
| :build-dir: app |
| :gen-args: -DEXTRA_CONF_FILE="overlay-ot.conf;overlay-prj.conf" |
| :goals: build |
| :compact: |
| |
| |
| Step 5: Sign the app image |
| ========================== |
| |
| The app image is the application itself that will be on the board. This app |
| will connect to UpdateHub server and check for new images. The image will be |
| loaded on the board with version 1.0.0. It is important check what file |
| format you SoC tools uses. In general, Zephyr can create images with binary |
| (``.bin``) image format or Intel's (``.hex``) image format. |
| |
| The Zephyr provide the ``west`` tool that simplify the signing process. Just |
| call west with proper parameter values: |
| |
| .. code-block:: console |
| |
| west sign -t imgtool -d build/app -- --version 1.0.0 --pad |
| --key bootloader/mcuboot/root-rsa-2048.pem |
| |
| === image configuration: |
| partition offset: 131072 (0x20000) |
| partition size: 393216 (0x60000) |
| rom start offset: 512 (0x200) |
| === signing binaries |
| unsigned bin: <zephyrdir>/build/app/zephyr/zephyr.bin |
| signed bin: <zephyrdir>/build/app/zephyr/zephyr.signed.bin |
| |
| |
| Step 6: Flash the app image |
| =========================== |
| |
| .. code-block:: console |
| |
| west flash -d build/app --bin-file build/app/zephyr/zephyr.signed.bin |
| |
| .. note:: Command variation to flash a ``hex`` file: |
| ``west flash -d build/app --hex-file build/app/zephyr/zephyr.signed.hex`` |
| |
| At this point you can access a third terminal ``terminal 3`` to check if image |
| is running. Open the ``terminal 3`` and press reset on your board: |
| |
| .. code-block:: console |
| |
| minicom -D /dev/ttyACM0 |
| |
| |
| Step 7: Signing the binary test image |
| ===================================== |
| |
| The test image needs different parameters to add the signature. Pay attention |
| to make sure you are creating the right signed image. The test image will be |
| created with version 2.0.0 in this tutorial: |
| |
| .. code-block:: console |
| |
| west sign --no-hex --bin -B build/zephyr-2.0.0.bin -t imgtool -d build/app -- |
| --version 2.0.0 --key bootloader/mcuboot/root-rsa-2048.pem |
| |
| === image configuration: |
| partition offset: 131072 (0x20000) |
| partition size: 393216 (0x60000) |
| rom start offset: 512 (0x200) |
| === signing binaries |
| unsigned bin: <zephyrdir>/build/app/zephyr/zephyr.bin |
| signed bin: build/zephyr-2.0.0.bin |
| |
| |
| Step 8: Create a package with UpdateHub Utilities (uhu) |
| ======================================================= |
| |
| First, install UpdateHub Utilities (``uhu``) on your system, using: |
| |
| .. code-block:: console |
| |
| pip3 install --user uhu |
| |
| After installing uhu you will need to set the ``product-uid``. The value for |
| UpdateHub-CE can be found at ``overlay-prj.conf.example`` file. For UpdateHub |
| Cloud, you need copy the value from the web interface. |
| |
| .. code-block:: console |
| |
| uhu product use "e4d37cfe6ec48a2d069cc0bbb8b078677e9a0d8df3a027c4d8ea131130c4265f" |
| |
| Then, add the package and its mode (``zephyr``): |
| |
| .. code-block:: console |
| |
| uhu package add build/zephyr-2.0.0.bin -m zephyr |
| |
| Then inform what ``version`` this image is: |
| |
| .. code-block:: console |
| |
| uhu package version 2.0.0 |
| |
| And finally you can build the package by running: |
| |
| .. code-block:: console |
| |
| uhu package archive --output build/zephyr-2.0.0.pkg |
| |
| The remaining steps are dedicated to UpdateHub-CE. If you are using UpdateHub |
| Cloud you can find the proper procedure at `docs.updatehub.io`_. |
| |
| |
| Step 9: Add the package to server |
| ================================= |
| |
| Now, add the package to the updatehub server. Open your browser to the server |
| URL, ``<your-ip-address>:8080``, and logging into the server using ``admin`` |
| as the login and password by default. After logging in, click on the package |
| menu, then ``UPLOAD PACKAGE``, and select the package built in step 8. |
| |
| |
| Step 10: Register device on server |
| ================================== |
| |
| If you chose ``Manual``, register your device at updatehub server by using the |
| terminal session where you are debugging the board ``terminal 3``. Type the |
| following command: |
| |
| .. code-block:: console |
| |
| updatehub run |
| |
| If everything is alright, it will print on the screen ``No update available``. |
| |
| For ``Polling`` mode, the system will automatically register your device after |
| :kconfig:option:`CONFIG_UPDATEHUB_POLL_INTERVAL` minutes. The ``updatehub run`` can |
| be used to speed-up. |
| |
| .. note:: |
| The message ``Could not receive data`` means that the application was not |
| able to reached the updatehub server for some reason. The most common |
| cases are server down, missing network routes and forget to change the |
| content of ``overlay-prj.conf`` file. |
| |
| |
| Step 11: Create a rollout |
| ========================= |
| |
| In the browser where the UpdateHub-CE is open, click on ``menu Rollout`` |
| and then ``CREATE ROLLOUT``. Select the version of the package that you added |
| in step 9. With that, the update is published, and the server is ready to |
| accept update requests. |
| |
| |
| Step 12: Run the update |
| ======================= |
| |
| Back in the terminal session that you used for debugging the board, type the |
| following command: |
| |
| .. code-block:: console |
| |
| updatehub run |
| |
| And then wait. The board will probe the server, check if there are any new |
| updates, and then download the update package you've just created. If |
| everything goes fine the message ``Image flashed successfully, you can reboot |
| now`` will be printed on the terminal. If you are using the ``Polling`` mode |
| the board will reboot automatically and Step 13 can be skipped. |
| |
| |
| Step 13: Reboot the system |
| ========================== |
| |
| In the terminal you used for debugging the board, type the following command: |
| |
| .. code-block:: console |
| |
| kernel reboot cold |
| |
| Your board will reboot and then start with the new image. After rebooting, |
| the board will automatically ping the server again and the message ``No update |
| available`` will be printed on the terminal. You can check the newer version |
| using the following command: |
| |
| .. code-block:: console |
| |
| uart:~$ updatehub info |
| Unique device id: acbdef0123456789 |
| Firmware Version: 2.0.0 |
| Product uid: e4d37cfe6ec48a2d069cc0bbb8b078677e9a0d8df3a027c4d8ea131130c4265f |
| UpdateHub Server: <server ip/dns> |
| uart:~$ |
| |
| Hardware |
| ******** |
| |
| The below list of hardware have been used by UpdateHub team. |
| |
| |
| .. csv-table:: |
| :header: "ID", "Network Interface", "Shield / Device" |
| :widths: 5, 45, 50 |
| :width: 800px |
| |
| 1, Ethernet, Native |
| 2, WIFI, :ref:`ESP-8266 <module_esp_8266>` |
| 3, "MODEM (PPP)", "SIMCOM 808" |
| 4, "IEEE 802.15.4 (6loWPAN)", "Native, |
| :ref:`RF2XX <atmel_at86rf2xx_transceivers>`" |
| 5, "BLE IPSP (6loWPAN)", Native |
| 6, "OpenThread Network", Native |
| |
| .. csv-table:: |
| :header: "Board", "Network Interface" |
| :widths: 50, 50 |
| :width: 800px |
| |
| :ref:`frdm_k64f`, "1, 2, 3, 4" |
| :ref:`nrf52840dk_nrf52840`, "2, 3, 4, 5, 6" |
| :ref:`nucleo_f767zi_board`, "1, 2, 3, 4" |
| |
| |
| .. _updatehub.io: https://updatehub.io |
| .. _docs.updatehub.io: https://docs.updatehub.io/ |
| .. _OpenThread Router: https://openthread.io/guides/border-router |