nRF5 SDK for Mesh v5.0.0
Integrating DFU process into the application

This page describes the stages that your application must include to make the DFU process work, and in particular the crucial API functions that are required.

After including these stages in your application, go to Configuring and performing DFU over Mesh to complete the DFU setup.

Table of contents


Initialization

The proprietary mesh DFU module is initialized and enabled by the Bluetooth mesh stack, when the application calls the functions mesh_stack_init and mesh_stack_start, respectively. No more actions are required on the application side.

See the following figure for an overview of the initialization process.

dfu_process_init.svg
DFU initialization
Note
The nrf_mesh_dfu_init will work correctly only after you flash the serial bootloader on all devices, which happens as part of Configuring and performing DFU over Mesh.

Once initialized, the proprietary mesh DFU module switches to the NRF_MESH_DFU_STATE_INITIALIZED state and starts advertising Firmware ID packets with the current firmware IDs.


Updating firmware

All DFU packets are received by the Bluetooth mesh stack (the scanner) and passed to the proprietary mesh DFU module by the nrf_mesh_dfu_rx function. This process does not require any actions from the application.

Note
While flash operations are in progress, the proprietary mesh DFU module is unable to receive packets.
dfu_process_receive.svg
Firmware update process

Receiving packets

Upon receiving a Firmware ID packet or a DFU state packet, the proprietary mesh DFU module notifies the application about a new firmware using NRF_MESH_EVT_DFU_FIRMWARE_OUTDATED (or NRF_MESH_EVT_DFU_FIRMWARE_OUTDATED_NO_AUTH) events. This happens before the firmware transfer begins, and the proprietary mesh DFU module will only notify the application if it has not started the reception of the firmware.

Depending on the the parameters supplied in nrf_mesh_evt_dfu_t::fw_outdated, the application may decide to either:

If neither nrf_mesh_dfu_request nor nrf_mesh_dfu_relay is called as a result of a NRF_MESH_EVT_DFU_FIRMWARE_OUTDATED (or NRF_MESH_EVT_DFU_FIRMWARE_OUTDATED_NO_AUTH) event, the update is ignored.

Requesting new firmware

If the application decides to receive new firmware, it must call the nrf_mesh_dfu_request function with the following elements specified:

Once nrf_mesh_dfu_request is called, the proprietary mesh DFU module switches to the target role and starts the DFU request timer, whose timeout is defined in NRF_MESH_DFU_REQ_TIMEOUT_US.

If no packets are received during the DFU request timer, the proprietary mesh DFU module notifies the application by sending the NRF_MESH_EVT_DFU_END event with the NRF_MESH_DFU_END_ERROR_TIMEOUT reason. At this point, the DFU process is finished.

Selecting a bank address

The bank address defines where the firmware image is to be stored while the transfer is in progress.

Make the application choose a bank address that has enough space for the entire firmware image, without overlapping with the final location of the transferred firmware.

Since the size info for the incoming firmware image is not available to the device in the firmware ID packet, leave as much space as possible for the bank and the resulting firmware location. To achieve this, place the bank address at the location that is calculated as the maximum of the following values: the middle of application flash area and the end of the application code. The address should be page-aligned. To find the persistent storage location, you can call mesh_stack_persistence_flash_usage.

For an example of the calculation, see DFU example.

Receiving new firmware

When the DFU process is started, the proprietary mesh DFU module sends the NRF_MESH_EVT_DFU_START event.

The process of receving DFU data packets is handled by the proprietary mesh DFU module in the background.

The proprietary mesh DFU module stores the received firmware in the bank at the provided address, which overrides the data stored at that address.

After processing each segment, the proprietary mesh DFU module starts the data transfer timer, whose timeout is defined in NRF_MESH_DFU_DATA_TRANSFER_TIMEOUT_US.

If no packets are received during the data transfer timer, the proprietary mesh DFU module notifies the application by sending the NRF_MESH_EVT_DFU_END event with the NRF_MESH_DFU_END_ERROR_TIMEOUT reason. At this point, the DFU process is finished.

Verifying new firmware

When the last segment is received, the proprietary mesh DFU module verifies the signature of the received firmware.

For more information about signing the firmware, see Security on the proprietary mesh DFU protocol page.

Flashing new firmware

Once the DFU process ends successfully and the bank is ready, the application receives NRF_MESH_EVT_DFU_BANK_AVAILABLE with the type of the bank (nrf_mesh_evt_dfu_t::bank).

The application can now call nrf_mesh_dfu_bank_flash to replace the current firmware with the new one. This process reboots the device. After the update, the bootloader switches to the application.

Note
Flashing new firmware triggers a restart of the chip. All non-volatile memory is lost during this call.

Relaying firmware

Upon receiving NRF_MESH_EVT_DFU_FIRMWARE_OUTDATED (or NRF_MESH_EVT_DFU_FIRMWARE_OUTDATED_NO_AUTH) event and depending on the the parameters supplied in nrf_mesh_evt_dfu_t::fw_outdated, the application can ask the proprietary mesh DFU module to relay DFU data packets coming from other relay nodes or target. This can happens, for example, when the application node has the latest version of firmware already installed.

To relay packets, the application must call the nrf_mesh_dfu_relay function and provide the DFU type nrf_mesh_dfu_type_t and the Firmware ID nrf_mesh_fwid_t of the firmware to be relayed. See the following figure.

dfu_process_relay.svg
Relaying firmware

The application can switch the proprietary mesh DFU module to the relay role by calling the nrf_mesh_dfu_relay function. The application can call this function upon receiving the NRF_MESH_EVT_DFU_FIRMWARE_OUTDATED (or NRF_MESH_EVT_DFU_FIRMWARE_OUTDATED_NO_AUTH) event, or at any other time.

When the relaying process is started, the proprietary mesh DFU module switches to NRF_MESH_DFU_STATE_RELAY state, sends the NRF_MESH_EVT_DFU_START event to the application and starts the DFU relay request timer, whose timeout is defined in NRF_MESH_DFU_RELAY_TIMEOUT_US.

If no packets are received during the relay request timer, the proprietary mesh DFU module notifies the application by sending the NRF_MESH_EVT_DFU_END event with the NRF_MESH_DFU_END_ERROR_TIMEOUT reason. At this point, the DFU process is finished.

After processing each segment the proprietary mesh DFU module starts the data transfer timer, whose timeout is defined in NRF_MESH_DFU_DATA_TRANSFER_TIMEOUT_US.

If no packets are received during during the data transfer timer, the proprietary mesh DFU module notifies the application by sending the NRF_MESH_EVT_DFU_END event with the NRF_MESH_DFU_END_ERROR_TIMEOUT reason. This is an expected way of finishing relaying firmware. At this point, the DFU process is finished.

When the DFU process is finished, the proprietary mesh DFU module is switched back to the NRF_MESH_DFU_STATE_INITIALIZED state and the application must call nrf_mesh_dfu_relay to start relaying the DFU data packets again.


Aborting transfer

The application can abort the ongoing DFU transfer by calling nrf_mesh_dfu_abort. The Bluetooth mesh DFU module is then switched to the NRF_MESH_DFU_STATE_INITIALIZED state.


Documentation feedback | Developer Zone | Subscribe | Updated