Device Firmware Upgrade module
Use the DFU module to perform the following:
Obtain the update image from Configuration channel and store it in the appropriate non-volatile memory partition.
Erase the non-volatile memory partition in the background before storing the update image.
Module events
Source Module |
Input Event |
This Module |
Output Event |
Sink Module |
---|---|---|---|---|
|
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Note
See the Application overview for more information about the event-based communication in the nRF Desktop application and about how to read this table.
Configuration
The module can be used for the following devices:
nRF52 and nRF53 Series - To perform the firmware upgrade, you must enable the bootloader. You can use the DFU module with either MCUboot or B0 bootloader. For more information on how to enable and configure a bootloader, see the nRF Desktop: Bootloader and Device Firmware Update section.
nRF54H Series - You can use the DFU module for the Software Update for Internet of Things (SUIT) procedure. The DFU module acts as a transport for the SUIT envelope used to update device firmware. For more information on how to enable the SUIT procedure, see the Software Update for Internet of Things (SUIT) section.
Enable the DFU module using the CONFIG_DESKTOP_CONFIG_CHANNEL_DFU_ENABLE option. It requires the transport option CONFIG_DESKTOP_CONFIG_CHANNEL_ENABLE to be selected, as it uses Configuration channel for the transmission of the update image.
Set the value of CONFIG_DESKTOP_CONFIG_CHANNEL_DFU_SYNC_BUFFER_SIZE to specify the size of the sync buffer (in words). During the DFU process, the data is initially stored in the buffer and then moved to non-volatile memory. The buffer is located in the RAM, so increasing the buffer size increases the RAM usage. If the buffer is small, the host must perform the DFU progress synchronization more often.
Important
The received update image chunks are stored on the dedicated non-volatile memory partition when the current version of the device firmware is running. For this reason, make sure that you use configuration with a dedicated update image partition. For more information on configuring the memory layout in the application, see the nRF Desktop: Memory layout documentation.
MCUboot bootloader mode
The MCUboot bootloader can either move the image to the primary slot before booting it (swap mode
) or boot the image directly from the secondary slot (direct-xip mode
).
If the MCUboot bootloader in the swap mode is selected, the DFU module does the following:
Requests the image upgrade after the whole image is transferred over the Configuration channel.
Confirms the running image after the device is rebooted.
If the MCUboot bootloader’s direct-xip mode is used, the module does not mark the newly uploaded image as pending and does not confirm it after a successful boot. In that case, the DFU module assumes that the MCUboot direct-xip bootloader simply boots an image with the higher version, so there is no need to mark the image as pending and confirm it.
The CONFIG_DESKTOP_CONFIG_CHANNEL_DFU_MCUBOOT_DIRECT_XIP option is used to inform the DFU module that the device uses the MCUboot bootloader in the direct-xip mode.
If the option is enabled, the DFU module reports the MCUBOOT+XIP
bootloader name instead of MCUBOOT
to indicate that the bootloader working in the direct-xip mode is used.
The option depends on enabling the MCUboot bootloader (CONFIG_BOOTLOADER_MCUBOOT
) and is enabled by default if the MCUboot direct-xip mode of operations is set (CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP
).
See the nRF Desktop: Bootloader and Device Firmware Update section for more information on the MCUboot bootloader configuration.
Device identification information
The DFU module provides the following information about the device through the Configuration channel:
Vendor ID (CONFIG_DESKTOP_CONFIG_CHANNEL_DFU_VID)
Product ID (CONFIG_DESKTOP_CONFIG_CHANNEL_DFU_PID)
Generation (CONFIG_DESKTOP_CONFIG_CHANNEL_DFU_GENERATION)
These values are fetched using the devinfo configuration channel option.
Note
By default, the reported Vendor ID, Product ID, and generation are aligned with the values defined globally for the nRF Desktop application. The default values of Kconfig options used by the DFU module are based on respectively CONFIG_DESKTOP_DEVICE_VID, CONFIG_DESKTOP_DEVICE_PID and CONFIG_DESKTOP_DEVICE_GENERATION.
Non-volatile memory access synchronization with other DFU methods
The DFU module leverages the DFU lock utility to synchronize non-volatile memory access with other DFU methods (for example, SMP DFU). If multiple DFU transports are enabled in your application configuration, make sure that the following conditions are met:
The CONFIG_DESKTOP_DFU_LOCK option is enabled
All of the used DFU transports use the DFU lock utility.
On each DFU attempt, the module attempts to claim ownership over the DFU non-volatile memory using the DFU Lock API. It holds the DFU owner status until the DFU process is completed or timed out. The lock is also kept during the background erase operation as it changes the DFU non-volatile memory content.
If the module is not the current DFU owner and cannot claim the DFU lock, it desists from performing requested actions that either modify the DFU non-volatile memory content or reboot the device.
The module also automatically starts the background erase operation of the DFU non-volatile memory once it becomes the lock owner after another DFU method.
Implementation details
The DFU module implementation is centered around the transmission and the storage of the update image, and it can be broken down into the following stages:
Protocol operations - How the module exchanges information with the host.
Partition preparation - How the module prepares for receiving an image.
The firmware transfer operation can also be carried out either by the Simple Management Protocol module or Device Firmware Upgrade MCUmgr module. Make sure that all enabled modules used for the firmware transfer operation use DFU lock utility to synchronize non-volatile memory access. If a module does not use the DFU lock utility, simultaneous modification of the data by the module and another application module might result in a broken image. This broken image will then be rejected by the bootloader.
Protocol operations
The DFU module depends on the Configuration channel for the correct and secure data transmission between the host and the device. The module provides a simple protocol that allows the update tool on the host to pass the update image to the device.
Note
All the described Configuration channel options are used by the HID configurator for nRF Desktop during the DFU. You can trigger DFU using a single command in the CLI.
The following Configuration channel options are available to perform the firmware update:
fwinfo - Passes the information about the currently executed image from the device to the host.
devinfo - Passes the identification information about the device from the device to the host.
reboot - Reboots the device.
start - Starts the new update image transmission.
data - Passes a chunk of the update image data from the host to the device.
sync - Checks the progress of the update image transmission.
module_variant - Provides the host with the information about the bootloader variant used on the device.
- fwinfo
Perform the fetch operation on this option to get the following information about the currently executed image:
Version and length of the image.
Partition ID of the currently booted image, used to specify the image placement.
Additionally, for the nRF54H Series, the following applies:
The reported image size is set to zero.
The booted image version is indicated by:
Root manifest sequence number that is encoded in the build number field.
Manifest semantic version, if supported by the SDFW (requires v0.6.2 or higher). The semantic version is encoded in the major, minor and patch fields. If semantic versioning is not supported, these fields are set to zero.
- devinfo
Perform the fetch operation on this option to get the following information about the device:
Vendor ID and Product ID
Generation
The device generation allows to distinguish configurations that use the same board and bootloader, but are not interoperable.
- reboot
Perform the fetch operation on this option to trigger an instant reboot of the device. After a successful image transfer, the reboot operation triggers a firmware update.
With the CONFIG_DESKTOP_DFU_LOCK option enabled, the device only executes this command when it holds the DFU owner status.
- start
Perform the set operation on this option to start the DFU. The operation contains the following data:
Size of the image being transmitted.
Checksum of the update image.
Offset at which the host tool is going to start the image update. If the image transfer is performed for the first time, the offset must be set to zero.
When the host tool performs the set operation, the checksum and the size are recorded and the update process is started.
If the transmission is interrupted, the current offset position is stored along with the image checksum and size until the device is rebooted. The host tool can restart the update image transfer after the interruption, but the checksum, the requested offset, and the size of the image must match the information stored by the device.
With the CONFIG_DESKTOP_DFU_LOCK option enabled, the device only executes this command when it holds the DFU owner status.
- data
Perform the set operation on this option to pass the chunk of the update image that should be stored at the current offset. The data is initially buffered in RAM, and then written to the non-volatile memory partition after a fetch operation is performed on the
sync
option.If the set operation on the
data
option is successful, the offset in buffer is increased. If the operation fails to be completed, the update process is interrupted.For performance reasons, the Configuration channel set operation does not return any information back to the host. To check that the update process is correct, the host tool must perform fetch operation on the
sync
option at regular intervals.With the CONFIG_DESKTOP_DFU_LOCK option enabled, the device only executes this command when it holds the DFU owner status.
Note
The DFU module does not check if the update image contains any valid data. It also does not check if it is correctly signed. When the update image is received, the host tool requests a reboot. Then, the bootloader will check the image for validity and ensure that the signature is correct. If the verification of the new images is successful, the new version of the application will boot.
- sync
Perform the fetch operation on this option to read the following data:
Information regarding the status of the update process. The module can report one of the following states:
DFU_STATE_ACTIVE_OTHER
- Another DFU process is ongoing and the application is receiving the new image from the host over a different DFU transport.DFU_STATE_CLEANING
- The module is erasing the update image non-volatile partition.DFU_STATE_STORING
- The module is writing data to the update image non-volatile partition.DFU_STATE_ACTIVE_CONFIG_CHANNEL
- The DFU is ongoing and the module is receiving the new image from the host.DFU_STATE_INACTIVE
- The module is not performing any operation, and the DFU can be started.
Size of the update image being transmitted.
Checksum of the update image.
Offset at which the update process currently is.
Size of the RAM buffer used to store the data. The host must synchronize the firmware image transfer progress at least on every synchronization buffer byte count.
The update tool can fetch the
sync
option before starting the update process to see at which offset the update is to be restarted.Fetching the
sync
option also triggers moving the image data from the RAM buffer to non-volatile memory.
- module_variant
Perform the fetch operation on this option to get the information about the bootloader variant that is being used on the device.
Writing data to non-volatile memory
The image data that is received from the host is initially buffered in the RAM.
Writing the data to non-volatile memory is triggered when the host performs the fetch operation on the sync
option.
At that point, the HID configurator for nRF Desktop waits until the data is written to non-volatile memory before providing more image data chunks.
The data is stored in a dedicated non-volatile memory partition using a dedicated work (k_work_delayable
).
The work stores a single chunk of data and resubmits itself.
To ensure that the non-volatile memory write will not interfere with the device usability, the stored data is split into small chunks and written only if there are no HID reports transmitted and the Bluetooth connection state does not change.
Partition preparation
Non-volatile flash memory must be erased before writing to it. The DFU module erases the update image partition before storing the update image data. This operation is done in the background. The erase operation is always performed for non-volatile update image partition.
To ensure that the memory erase will not interfere with the device usability, the memory pages are erased only if there are no HID reports transmitted and the Bluetooth connection state does not change. For example, the memory is not erased right after the Bluetooth connection is established.
Note
The DFU process cannot be started before the entire partition used for storing the update image is erased. If the DFU command is rejected, you must wait until the non-volatile memory area used for the update image is erased.
SUIT integration
The module can act as a transport for the SUIT DFU procedure.
The module receives the SUIT envelope with update image data over the Configuration channel and stores the envelope to a dedicated DFU partition (dfu_partition
defined in the DTS).
After a complete transfer, the reboot command triggers a firmware update using the envelope.
The module calls the suit_trigger_update()
function to trigger an update instead of rebooting the device using the sys_reboot()
function.
Triggering an update using the reboot command makes the user experience consistent with nRF52 and nRF53 Series devices.
For these devices, the reboot command after a complete update image transfer triggers an image update performed by the bootloader.