The Thread Secure DFU example consists of two components: a bootloader and a DFU client. The bootloader is used to verify application integrity and to install a new application image. The DFU client is a module that is typically incorporated into the user application. This allows for downloading a new image while the user application is running. This mechanism differs from the one in the BLE Secure DFU Bootloader where a new image is downloaded and installed in the bootloader.
Thread Secure DFU accepts images that contain a new bootloader or application, which contains the Thread network stack. To protect the target device against malicious attackers trying to impersonate the rightful sender of the firmware update, the init packet of the firmware package must be signed.
Thread Secure DFU does not use a SoftDevice, but the bootloader requires the Master Boot Record (MBR). The example provides a stand-alone MBR as a .hex file. To program the MBR, perform the following steps:
<InstallFolder>\examples\thread\experimental\dfu\mbr
.nrfjprog -f nrf52 -r --program mbr_nrf52_2.2.0-1.alpha_mbr.hex --chiperase
The bootloader for the Thread Secure DFU is implemented using Bootloader modules. The main role of the bootloader is to check application integrity and, in case of dual bank updates (see Dual-bank and single-bank updates), to transfer the new image to the active bank. Unlike the BLE Secure DFU Bootloader, the bootloader for Thread Secure DFU does not initialize any transports. Therefore, DFU is not possible in the bootloader. If a valid application is missing, the bootloader enters an infinite loop.
During system startup, the Master Boot Record (MBR) is responsible for starting the bootloader. To do this, the MBR must know the start address of the bootloader. This start address is defined in UICR.BOOTLOADERADDR
, which is located at address 0x10001014 (see NRF_UICR_BOOTLOADER_START_ADDRESS
). Therefore, you must set UICR.BOOTLOADERADDR
to the correct value when you program the bootloader.
Programming the bootloader requires the following steps:
armgcc
folder of the example at <InstallFolder>\examples\thread\experimental\dfu\bootloader\pca10056\blank\armgcc
.make
to build the project._build
folder to the board. For example, nrfjprog -f nrf52 -r --program __build\file.hex --sectoranduicrerase
.To download the version of nrfutil that supports DFU over Thread, go to nRF5 SDK for Thread product page. This is not an official version of nrfutil, but it contains customizations that make it possible to run DFU over Thread. After downloading, follow this procedure to install nrfutil from source.
The DFU process flow in the Thread Secure DFU is slightly different from, for example, the BLE Secure DFU Bootloader DFU process flow.
The are two entities which participate in the Thread Secure DFU process: a DFU client and a DFU server. The DFU client runs on a DFU target, which is the device that is being upgraded, and is responsible for downloading and installing the new firmware. The DFU client incorporates a DFU controller (see Device Firmware Update process) which manages the DFU process. This means that each DFU target might be in a different state regarding the DFU process at a given point of time. The DFU server is a stateless server which provides a firmware package. For example, the DFU server could be a cloud service, an nRF52840 Development Kit in conjunction with nrfutil, or a mobile phone running an application.
The DFU client is a module which is typically integrated with the user application. The module uses the IoT SDK CoAP library to implement a DFU algorithm which runs concurrently to the user application. The Thread Secure DFU example shows how the module should be initialized and triggered from a user application.
The basic operation of the DFU client is as follows:
coap_dfu_init()
function, the DFU client binds to DFU_UDP_PORT
(by default 5683).The DFU client checks for availability of new firmware packages by sending a trigger packet using the coap_dfu_trigger()
function. The trigger packet can be sent to a particular host or to a group of hosts using a multicast address. The former method is useful in a scenario where the DFU server is outside of the Thread network, for example, hosted in the cloud.
Thread Secure DFU uses the same packet format as the BLE Secure DFU Bootloader. Refer to Init packet for details regarding the init packet customization.
Firmware packages for Thread Secure DFU are created using the same method as in the BLE Secure DFU Bootloader. Refer to Creating a firmware package to find out how to create a firmware package.
--sd-req
option is required for compatibility reasons. You can provide any value for the option as it is ignored during DFU.Thread Secure DFU uses the same validation algorithm as BLE Secure DFU Bootloader. Refer to Validation for details of the validation algorithm.
To test the DFU process, you need two nRF52840 Development Kit boards. One of these boards will play the role of a DFU client that will be updated, while the second one will be a DFU server that distributes the new firmware. Unless stated otherwise, run all of the presented commands in the main folder of the DFU Example: <InstallFolder>\examples\thread\experimental\dfu
.
Test the Thread Secure DFU application by performing the following steps:
dfu_public_key.c:
dfu_public_key.c
file to the project folder <InstallFolder>\examples\dfu\dfu_req_handling
, replacing the existing file. <InstallFolder>\examples\thread\experimental\dfu
. Use the path provided above.make
command in <InstallFolder>\examples\thread\experimental\dfu\client\pca10056\blank\armgcc
.main()
function: make
command in <InstallFolder>\examples\thread\experimental\dfu\client\pca10056\blank\armgcc
.COM3
is the DFU Server DK serial port: -a
option. For more information, enter nrfutil dfu thread --help
.When adding a bootloader to your device, you must be aware of where in the device memory the different firmware components are located. The following table shows the memory layout used by the Thread Secure DFU.
Usage | Memory range nRF52840 |
---|---|
Bootloader settings | 0x000F F000 - 0x0010 0000 (4 kB) |
MBR parameter storage | 0x000F E000 - 0x000F F000 (4 kB) |
Bootloader | 0x000F 8000 - 0x000F E000 (24 kB) |
OpenThread settings | 0x000F 4000 - 0x000F 8000 (16 kB) |
Application area (incl. free space) | 0x0001 F000 - 0x000F 4000 (852 kB) |
Reserved | 0x0000 1000 - 0x0001 F000 (120 kB) |
Master Boot Record (MBR) | 0x0000 0000 - 0x0000 1000 (4 kB) |