1.. zephyr:code-sample:: updatehub-fota
2 :name: UpdateHub embedded Firmware Over-The-Air (FOTA) update
3 :relevant-api: updatehub
4
5 Perform Firmware Over-The-Air (FOTA) updates using UpdateHub.
6
7Overview
8********
9
10UpdateHub is an enterprise-grade solution which makes it simple to remotely
11update all your embedded devices. It handles all aspects related to sending
12Firmware Over-the-Air (FOTA) updates with maximum security and efficiency,
13while you focus on adding value to your product. It is possible to read more
14about at `docs.updatehub.io`_.
15
16This sample shows how to use UpdateHub in both a polling and manual update
17mode.
18
19Polling mode runs automatically on a predefined period, probing the server
20for updates and installing them without requiring user intervention.
21
22Manual mode requires the user to call the server probe and then, if there is
23an available update, also requires the user to decide if it is appropriate to
24update now or later.
25
26You can access the sample source code at
27:zephyr_file:`samples/subsys/mgmt/updatehub/src/main.c`.
28
29Caveats
30*******
31
32* The Zephyr port of ``UpdateHub`` was initially developed to run on a
33 :ref:`Freedom-K64F <frdm_k64f>` kit using the ethernet connectivity. The
34 application should build and run for other platforms with same connectivity.
35
36* The sample provides overlay files to enable other technologies like WIFI,
37 modem, BLE IPSP, 802.15.4 or OpenThread. These technologies depends on
38 hardware resources and the correspondent overlay was designed to be generic
39 instead full optimized.
40
41* It is important understand that some wireless technologies may require a
42 gateway or some sort of border router. It is out of scope provide such
43 configuration in details.
44
45* The MCUboot bootloader is required for ``UpdateHub`` function properly.
46 Before chose a platform to test, make sure that SoC and board have support
47 to it. UpdateHub currently uses two slots to perform the upgrade. More
48 information about Device Firmware Upgrade subsystem and MCUboot can be found
49 in :ref:`mcuboot`.
50
51* ``UpdateHub`` acts like a service on Zephyr. It is heavily dependent on
52 Zephyr sub-systems and it uses CoAP over UDP.
53
54
55Building and Running
56********************
57
58The below steps describe how to build and run the ``UpdateHub`` sample in
59Zephyr. Open a terminal ``terminal 1`` and navigate to your Zephyr project
60directory. This allows to construct and run everything from a common place.
61
62.. code-block:: console
63
64 ls
65 bootloader modules tools zephyr
66
67
68Step 1: Build/Flash MCUboot
69===========================
70
71The MCUboot can be build following the instructions in the :ref:`mcuboot`
72documentation page. Flash the resulting image file using west on
73``terminal 1``.
74
75.. zephyr-app-commands::
76 :zephyr-app: bootloader/mcuboot/boot/zephyr
77 :board: frdm_k64f
78 :build-dir: mcuboot-frdm_k64f
79 :goals: build flash
80
81
82Step 2: Start the UpdateHub Server
83==================================
84
85Step 2.1: UpdateHub-CE (Community Edition)
86------------------------------------------
87
88The Zephyr sample application is configured by default to use the UpdateHub-CE
89server edition. This version implies you need run your own server. The
90UpdateHub-CE is distributed as a docker container and can be on your local
91network or even installed on a service provider like Digital Ocean, Vultr etc.
92To start using the UpdateHub-CE simple execute the docker command with the
93following parameters on another terminal ``terminal 2``.
94
95.. code-block:: console
96
97 docker run -it -p 8080:8080 -p 5683:5683/udp --rm
98 updatehub/updatehub-ce:latest
99
100Step 2.2: UpdateHub Cloud
101-------------------------
102
103The UpdateHub Cloud is an enterprise-grade solution. It provides almost same
104resources than UpdateHub-CE with the DTLS as main diferential. For more
105details on how to use the UpdateHub Cloud please refer to the documentation on
106`updatehub.io`_. The UpdateHub Cloud has the option to use CoAPS/DTLS or not.
107If you want to use the CoAPS/DTLS, simply add the ``overlay-dtls.conf`` when
108building the sample. You can use the provided certificate for test this
109example or create your own. The below procedure instruct how create a new
110certificate using openssl on a Linux machine on terminal ``terminal 2``.
111
112.. code-block:: console
113
114 openssl genrsa -out privkey.pem 512
115 openssl req -new -x509 -key privkey.pem -out servercert.pem
116
117The ``servercert`` and ``privkey`` files must be embedded in the application
118by ``certificates.h`` file. The following procedure can be used to generated
119the required ``der`` files:
120
121.. code-block:: console
122
123 openssl x509 -in servercert.pem -outform DER -out servercert.der
124 openssl pkcs8 -topk8 -inform PEM -outform DER -nocrypt -in privkey.pem
125 -out privkey.der
126
127
128The ``der`` files should be placed on the sample source at certificates
129directory.
130
131.. note::
132
133 When using UpdateHub Cloud server it is necessary update your own
134 ``overlay-prj.conf`` with option :kconfig:option:`CONFIG_UPDATEHUB_CE` equal ``n``.
135
136
137Step 3: Configure UpdateHub Sample
138==================================
139
140The updatehub have several Kconfig options that are necessary configure to
141make it work or tune communication.
142
143Set :kconfig:option:`CONFIG_UPDATEHUB_CE` select between UpdateHub edition. The ``y``
144value will select UpdateHub-CE otherwise ``n`` selects UpdateHub Cloud.
145
146Set :kconfig:option:`CONFIG_UPDATEHUB_SERVER` with your local IP address that runs the
147UpdateHub-CE server edition. If your are using a service provider a DNS name
148is a valid option too. This option is only valid when using UpdateHub-CE.
149
150Set :kconfig:option:`CONFIG_UPDATEHUB_POLL_INTERVAL` with the polling period of your
151preference, remembering that the limit is between 0 and 43200 minutes
152(30 days). The default value is 1440 minutes (24h).
153
154Set :kconfig:option:`CONFIG_UPDATEHUB_PRODUCT_UID` with your product ID. When using
155UpdateHub-CE the valid is available at ``overlay-prj.conf.example`` file.
156
157
158Step 4: Build UpdateHub App
159===========================
160
161In order to correctly build UpdateHub the overlay files must be use correctly.
162More information about overlay files in :ref:`important-build-vars`.
163
164.. note::
165 It is out of scope at this moment provide support for experimental
166 features. However, the configuration and use is similar to the start
167 point indicated on the experimental network interface.
168
169Step 4.1: Build for Ethernet
170----------------------------
171
172The ethernet depends only from base configuration.
173
174.. zephyr-app-commands::
175 :zephyr-app: zephyr/samples/subsys/mgmt/updatehub
176 :board: [ frdm_k64f | nucleo_f767zi ]
177 :build-dir: app
178 :gen-args: -DEXTRA_CONF_FILE=overlay-prj.conf
179 :goals: build
180 :compact:
181
182Step 4.2: Build for WiFi
183------------------------
184
185For WiFi, it needs add ``overlay-wifi.conf``. Here a shield provides WiFi
186connectivity using, for instance, arduino headers. See :ref:`module_esp_8266`
187for details.
188
189.. zephyr-app-commands::
190 :zephyr-app: zephyr/samples/subsys/mgmt/updatehub
191 :board: [ frdm_k64f | nrf52840dk_nrf52840 | nucleo_f767zi ]
192 :build-dir: app
193 :gen-args: -DEXTRA_CONF_FILE="overlay-wifi.conf;overlay-prj.conf"
194 :shield: esp_8266_arduino
195 :goals: build
196 :compact:
197
198.. note::
199 The board disco_l475_iot1 is not supported. The es-WIFI driver currently
200 doesn't support UDP.
201
202Step 4.3: Build for Modem
203-------------------------
204
205Modem needs add ``overlay-modem.conf``. Now, a DTC overlay file is used to
206configure the glue between the modem and an arduino headers. The modem config
207uses PPP over GSM modem, see :zephyr:code-sample:`gsm-modem` sample application.
208
209.. zephyr-app-commands::
210 :zephyr-app: zephyr/samples/subsys/mgmt/updatehub
211 :board: [ frdm_k64f | nrf52840dk_nrf52840 | nucleo_f767zi ]
212 :build-dir: app
213 :gen-args: -DEXTRA_CONF_FILE="overlay-modem.conf;overlay-prj.conf" \
214 -DDTC_OVERLAY_FILE=arduino.overlay
215 :goals: build
216 :compact:
217
218Step 4.4: Build for IEEE 802.15.4 [experimental]
219------------------------------------------------
220
221For IEEE 802.15.4 needs add ``overlay-802154.conf``. This requires two nodes:
222one will be the host and the second one will be the device under test. The
223validation needs a Linux kernel >= 4.9 with all 6loWPAN support. The start
224point is try reproduce the Zephyr :zephyr:code-sample:`wpan-usb`. It is out of scope
225at this moment provide support since it is experimental. The gateway was
226tested with both native linux driver and ``atusb`` and with ``wpanusb`` sample.
227
228.. zephyr-app-commands::
229 :zephyr-app: zephyr/samples/subsys/mgmt/updatehub
230 :board: nrf52840dk_nrf52840
231 :build-dir: app
232 :gen-args: -DEXTRA_CONF_FILE="overlay-802154.conf;overlay-prj.conf"
233 :goals: build
234 :compact:
235
236.. zephyr-app-commands::
237 :zephyr-app: zephyr/samples/subsys/mgmt/updatehub
238 :board: [ frdm_k64f | nucleo_f767zi ]
239 :build-dir: app
240 :gen-args: -DEXTRA_CONF_FILE="overlay-802154.conf;overlay-prj.conf"
241 :shield: atmel_rf2xx_arduino
242 :goals: build
243 :compact:
244
245Step 4.5: Build for BLE IPSP [experimental]
246-------------------------------------------
247
248The BLE IPSP needs ``overlay-ipsp.conf``. This may requires two nodes:
249one will be the host and the second one will be the device under test. The
250validation needs a Linux kernel >= 4.9 with all 6loWPAN support. In this
251particular case the Bluetooth 6LoWPAN module is needed. The start point is try
252reproduce the Zephyr :ref:`bluetooth-ipsp-sample`. It is out of scope
253at this moment provide support since it is experimental. The gateway was
254tested with native linux driver and an USB dongle.
255
256.. zephyr-app-commands::
257 :zephyr-app: zephyr/samples/subsys/mgmt/updatehub
258 :board: nrf52840dk_nrf52840
259 :build-dir: app
260 :gen-args: -DEXTRA_CONF_FILE="overlay-ipsp.conf;overlay-prj.conf"
261 :goals: build
262 :compact:
263
264Step 4.6: Build for OpenThread Network [experimental]
265-----------------------------------------------------
266
267The OpenThread requires the ``overlay-ot.conf``. It requires two nodes:
268one will be the host NCP and the second one will be the device under test. The
269validation needs a Linux kernel >= 4.9 with optional NAT-64 support. The
270start point is try reproduce the `OpenThread Router`_. It is
271out of scope at this moment provide support since it is experimental. The
272gateway was tested using two boards with OpenThread 1.1.1 on NCP mode.
273
274.. zephyr-app-commands::
275 :zephyr-app: zephyr/samples/subsys/mgmt/updatehub
276 :board: nrf52840dk_nrf52840
277 :build-dir: app
278 :gen-args: -DEXTRA_CONF_FILE="overlay-ot.conf;overlay-prj.conf"
279 :goals: build
280 :compact:
281
282
283Step 5: Sign the app image
284==========================
285
286The app image is the application itself that will be on the board. This app
287will connect to UpdateHub server and check for new images. The image will be
288loaded on the board with version 1.0.0. It is important check what file
289format you SoC tools uses. In general, Zephyr can create images with binary
290(``.bin``) image format or Intel's (``.hex``) image format.
291
292The Zephyr provide the ``west`` tool that simplify the signing process. Just
293call west with proper parameter values:
294
295.. code-block:: console
296
297 west sign -t imgtool -d build/app -- --version 1.0.0 --pad
298 --key bootloader/mcuboot/root-rsa-2048.pem
299
300 === image configuration:
301 partition offset: 131072 (0x20000)
302 partition size: 393216 (0x60000)
303 rom start offset: 512 (0x200)
304 === signing binaries
305 unsigned bin: <zephyrdir>/build/app/zephyr/zephyr.bin
306 signed bin: <zephyrdir>/build/app/zephyr/zephyr.signed.bin
307
308
309Step 6: Flash the app image
310===========================
311
312.. code-block:: console
313
314 west flash -d build/app --bin-file build/app/zephyr/zephyr.signed.bin
315
316.. note:: Command variation to flash a ``hex`` file:
317 ``west flash -d build/app --hex-file build/app/zephyr/zephyr.signed.hex``
318
319At this point you can access a third terminal ``terminal 3`` to check if image
320is running. Open the ``terminal 3`` and press reset on your board:
321
322.. code-block:: console
323
324 minicom -D /dev/ttyACM0
325
326
327Step 7: Signing the binary test image
328=====================================
329
330The test image needs different parameters to add the signature. Pay attention
331to make sure you are creating the right signed image. The test image will be
332created with version 2.0.0 in this tutorial:
333
334.. code-block:: console
335
336 west sign --no-hex --bin -B build/zephyr-2.0.0.bin -t imgtool -d build/app --
337 --version 2.0.0 --key bootloader/mcuboot/root-rsa-2048.pem
338
339 === image configuration:
340 partition offset: 131072 (0x20000)
341 partition size: 393216 (0x60000)
342 rom start offset: 512 (0x200)
343 === signing binaries
344 unsigned bin: <zephyrdir>/build/app/zephyr/zephyr.bin
345 signed bin: build/zephyr-2.0.0.bin
346
347
348Step 8: Create a package with UpdateHub Utilities (uhu)
349=======================================================
350
351First, install UpdateHub Utilities (``uhu``) on your system, using:
352
353.. code-block:: console
354
355 pip3 install --user uhu
356
357After installing uhu you will need to set the ``product-uid``. The value for
358UpdateHub-CE can be found at ``overlay-prj.conf.example`` file. For UpdateHub
359Cloud, you need copy the value from the web interface.
360
361.. code-block:: console
362
363 uhu product use "e4d37cfe6ec48a2d069cc0bbb8b078677e9a0d8df3a027c4d8ea131130c4265f"
364
365Then, add the package and its mode (``zephyr``):
366
367.. code-block:: console
368
369 uhu package add build/zephyr-2.0.0.bin -m zephyr
370
371Then inform what ``version`` this image is:
372
373.. code-block:: console
374
375 uhu package version 2.0.0
376
377And finally you can build the package by running:
378
379.. code-block:: console
380
381 uhu package archive --output build/zephyr-2.0.0.pkg
382
383The remaining steps are dedicated to UpdateHub-CE. If you are using UpdateHub
384Cloud you can find the proper procedure at `docs.updatehub.io`_.
385
386
387Step 9: Add the package to server
388=================================
389
390Now, add the package to the updatehub server. Open your browser to the server
391URL, ``<your-ip-address>:8080``, and logging into the server using ``admin``
392as the login and password by default. After logging in, click on the package
393menu, then ``UPLOAD PACKAGE``, and select the package built in step 8.
394
395
396Step 10: Register device on server
397==================================
398
399If you chose ``Manual``, register your device at updatehub server by using the
400terminal session where you are debugging the board ``terminal 3``. Type the
401following command:
402
403.. code-block:: console
404
405 updatehub run
406
407If everything is alright, it will print on the screen ``No update available``.
408
409For ``Polling`` mode, the system will automatically register your device after
410:kconfig:option:`CONFIG_UPDATEHUB_POLL_INTERVAL` minutes. The ``updatehub run`` can
411be used to speed-up.
412
413.. note::
414 The message ``Could not receive data`` means that the application was not
415 able to reached the updatehub server for some reason. The most common
416 cases are server down, missing network routes and forget to change the
417 content of ``overlay-prj.conf`` file.
418
419
420Step 11: Create a rollout
421=========================
422
423In the browser where the UpdateHub-CE is open, click on ``menu Rollout``
424and then ``CREATE ROLLOUT``. Select the version of the package that you added
425in step 9. With that, the update is published, and the server is ready to
426accept update requests.
427
428
429Step 12: Run the update
430=======================
431
432Back in the terminal session that you used for debugging the board, type the
433following command:
434
435.. code-block:: console
436
437 updatehub run
438
439And then wait. The board will probe the server, check if there are any new
440updates, and then download the update package you've just created. If
441everything goes fine the message ``Image flashed successfully, you can reboot
442now`` will be printed on the terminal. If you are using the ``Polling`` mode
443the board will reboot automatically and Step 13 can be skipped.
444
445
446Step 13: Reboot the system
447==========================
448
449In the terminal you used for debugging the board, type the following command:
450
451.. code-block:: console
452
453 kernel reboot cold
454
455Your board will reboot and then start with the new image. After rebooting,
456the board will automatically ping the server again and the message ``No update
457available`` will be printed on the terminal. You can check the newer version
458using the following command:
459
460.. code-block:: console
461
462 uart:~$ updatehub info
463 Unique device id: acbdef0123456789
464 Firmware Version: 2.0.0
465 Product uid: e4d37cfe6ec48a2d069cc0bbb8b078677e9a0d8df3a027c4d8ea131130c4265f
466 UpdateHub Server: <server ip/dns>
467 uart:~$
468
469Hardware
470********
471
472The below list of hardware have been used by UpdateHub team.
473
474
475.. csv-table::
476 :header: "ID", "Network Interface", "Shield / Device"
477 :widths: 5, 45, 50
478 :width: 800px
479
480 1, Ethernet, Native
481 2, WIFI, :ref:`ESP-8266 <module_esp_8266>`
482 3, "MODEM (PPP)", "SIMCOM 808"
483 4, "IEEE 802.15.4 (6loWPAN)", "Native,
484 :ref:`RF2XX <atmel_at86rf2xx_transceivers>`"
485 5, "BLE IPSP (6loWPAN)", Native
486 6, "OpenThread Network", Native
487
488.. csv-table::
489 :header: "Board", "Network Interface"
490 :widths: 50, 50
491 :width: 800px
492
493 :ref:`frdm_k64f`, "1, 2, 3, 4"
494 :ref:`nrf52840dk_nrf52840`, "2, 3, 4, 5, 6"
495 :ref:`nucleo_f767zi_board`, "1, 2, 3, 4"
496
497
498.. _updatehub.io: https://updatehub.io
499.. _docs.updatehub.io: https://docs.updatehub.io/
500.. _OpenThread Router: https://openthread.io/guides/border-router
501