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