nRF5 SDK for Thread
Thread Secure DFU Example

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.

MBR setup

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:

  1. Open a command prompt and navigate to <InstallFolder>\examples\thread\experimental\dfu\mbr.
  2. Ensure that nrfjprog (from nRF5x Command Line Tools v9.2.0 or newer) is in the path, thus the path to nrfjprog.exe is part of the PATH environment variable.
  3. Run the following command: nrfjprog -f nrf52 -r --program mbr_nrf52_2.2.0-1.alpha_mbr.hex --chiperase

Bootloader setup

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:

  1. Navigate to the armgcc folder of the example at <InstallFolder>\examples\thread\experimental\dfu\bootloader\pca10056\blank\armgcc.
  2. Open a command prompt and run make to build the project.
  3. Use nrfjprog (from nRF5x Command Line Tools v9.2.0 or newer) to program the .hex file that was created in the _build folder to the board. For example, nrfjprog -f nrf52 -r --program __build\file.hex --sectoranduicrerase.

DFU client

Note
nRF5 SDK for Thread uses a custom version of nrfutil.

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:

  1. Once initialized with the coap_dfu_init() function, the DFU client binds to DFU_UDP_PORT (by default 5683).
  2. The DFU client waits for a trigger packet. The trigger packet contains information about firmware size and checksum.
  3. If the installed firmware size or checksum differs from the size or checksum sent in the trigger packet, the DFU client requests the init packet from the DFU server which has sent the trigger packet.
  4. Once the init packet is downloaded, a validation procedure is performed (see Validation).
  5. If validation is successful, then the firmware image download starts.
  6. Once the firmware image is downloaded, the DFU client checks its integrity. If it is successful, the device is restarted and the new image is copied into the active bank.

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.

Init packet

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.

Creating a firmware package

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.

Note
The Thread stack does not use the SoftDevice, but the --sd-req option is required for compatibility reasons. You can provide any value for the option as it is ignored during DFU.

Validation

Thread Secure DFU uses the same validation algorithm as BLE Secure DFU Bootloader. Refer to Validation for details of the validation algorithm.

Testing

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:

  1. Create cryptographic keys for the example. See Working with keys for information about key generation.
    1. Create a private key:
      nrfutil keys generate priv.pem
    2. Create a public key in code format and store it in a file named dfu_public_key.c:
      nrfutil keys display --key pk --format code priv.pem --out_file dfu_public_key.c
    3. Copy the dfu_public_key.c file to the project folder <InstallFolder>\examples\dfu\dfu_req_handling, replacing the existing file.
      Note
      Do not copy the key to folder <InstallFolder>\examples\thread\experimental\dfu. Use the path provided above.
  2. Build the bootloader as described in Bootloader setup.
  3. Prepare the DFU Client:
    1. Install micro-ecc. This library is required by the Cryptography library , which is used by the Thread Secure DFU example.
    2. Compile the DFU client by running the make command in <InstallFolder>\examples\thread\experimental\dfu\client\pca10056\blank\armgcc.
    3. Return to the DFU example main folder and generate a bootloader settings HEX file:
      nrfutil settings generate --family NRF52 --application client\pca10056\blank\armgcc\_build\nrf52840_xxaa.hex --application-version 1 --bootloader-version 1 --bl-settings-version 1 settings.hex
    4. Use mergehex (part of the nRF5x Command Line Tools) to merge the client HEX file and the bootloader settings HEX file:
      mergehex -m client\pca10056\blank\armgcc\_build\nrf52840_xxaa.hex settings.hex -o dfu_client.hex
  4. Flash the DFU Client to the board:
    1. Connect the DFU Client board to the computer.
    2. Flash the MBR as described in MBR setup.
    3. Flash the bootloader as described in Bootloader setup.
    4. Flash the merged DFU Client with the following command:
      nrfjprog -f nrf52 -r --program dfu_client.hex --sectorerase
    5. Make sure that the device connects to the Thread network. This is indicated by LED 1 being lit.
  5. Prepare the firmware package for the DFU process:
    1. To successfully perform the DFU process, you need to modify the DFU Client application, so that the new firmware has a different checksumcd _build. For example, add the following line to the main() function:
      LEDS_ON(BSP_LED_3_MASK);
    2. Compile the modified DFU Client by running the make command in <InstallFolder>\examples\thread\experimental\dfu\client\pca10056\blank\armgcc.
    3. Return to the DFU example main folder and prepare a firmware package (in ZIP format) with the new firmware. See Creating a firmware package for more information:
      nrfutil pkg generate --hw-version 52 --sd-req 0xff --application-version 2 --application client\pca10056\blank\armgcc\_build\nrf52840_xxaa.hex --key-file priv.pem app_dfu_package.zip
  6. Use nrfutil to run the DFU:
    1. Connect the second nRF52840 Development Kit board to your computer. This board serves as the connectivity IC to the Thread network. This board does not require installation of any firmware. It will be flashed by nrfutil.
    2. Run the following command to start the DFU process over Thread, where COM3 is the DFU Server DK serial port:
      nrfutil dfu thread -f -pkg app_dfu_package.zip -p COM3
    3. By default, DFU is performed on all conforming devices in the network. To choose a specific target device using its IPv6 address, use nrfutil's -a option. For more information, enter nrfutil dfu thread --help.
  7. Observe that the device resets and runs the new application.

Memory Layout

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)

Documentation feedback | Developer Zone | Subscribe | Updated