Running the DFU process
This user guide introduces basic information of the DFU and provides an example procedure for running it on your application.
The DFU process in this SDK uses MCUboot, a secure bootloader for 32-bit microcontrollers. MCUboot allows for safe firmware updates with minimal overhead.
Firmware updates are transferred to a device using MCUmgr, which has transports for Bluetooth Low Energy® and UART.
More detailed information about specific concepts can be found in Memory Partitioning for DFU and Bootloader keys sections.
Partition Configuration
The memory of your device must be partitioned appropriately to accommodate the bootloader, application, and firmware update mechanisms. Bare Metal uses Zephyr’s DTS system for memory partitioning.
For details on memory partitioning and related concepts, see Memory Partitioning for DFU. If you are not using a DK board target, refer to Preparing the DFU-ready variant of your board for an example of how to partition the memory using DTS.
Firmware loader
The firmware loader is a crucial application for updating the main application via a transport layer, such as Bluetooth LE.
Note
When using Bluetooth LE as transport, make sure to enable the SB_CONFIG_BM_FIRMWARE_LOADER_BT_MCUMGR sysbuild Kconfig option.
The firmware loader can be activated by the bootloader using the following methods:
- Using a button (GPIO)
Set the
SB_CONFIG_BM_BOOTLOADER_MCUBOOT_FIRMWARE_LOADER_ENTRANCE_GPIOsysbuild Kconfig option to use this mode.
- Using the reset pin
Set the
SB_CONFIG_BM_BOOTLOADER_MCUBOOT_FIRMWARE_LOADER_ENTRANCE_PIN_RESETsysbuild Kconfig option to use this mode.
- Buttonless entry through the retention register from the application
Set the
SB_CONFIG_BM_BOOTLOADER_MCUBOOT_FIRMWARE_LOADER_ENTRANCE_BOOT_MODEsysbuild Kconfig option to use this mode.
Installer Application
The installer application is automatically generated by the build system. It updates the firmware loader and SoftDevice images on the device.
Output build files (image files)
When DFU is enabled in the application, the build system outputs the following files.
File |
Description |
Programming scenario |
|---|---|---|
|
Firmware loader image. |
Programming board targets. |
|
MCUBoot image with SoftDevice. |
|
|
Application image. |
|
|
Production hex file, containing: MCUboot, firmware loader, SoftDevice and main application images. |
Production device programming. |
|
Installer Update image (DFU) with SoftDevice and firmware loader updates. |
DFU process for board targets. |
|
Application Update image (DFU). |
Running DFU in your application
The following is the workflow for testing the DFU mechanism on an application developed with Bare Metal.
Note
The preparation below here describes how to add a MCUboot board variant to a custom board, for Bare Metal there already are MCUboot board variants for the bm_nrf54l15dk board:
bm_nrf54l15dk/nrf54l05/cpuapp/s115_softdevice/mcubootfor nRF54L15 (emulating nRF54L05) with S115 softdevice
bm_nrf54l15dk/nrf54l10/cpuapp/s115_softdevice/mcubootfor nRF54L15 (emulating nRF54L10) with S115 softdevice
bm_nrf54l15dk/nrf54l15/cpuapp/s115_softdevice/mcubootfor nRF54L15 with S115 softdevice
To test DFU with one of these default board targets, skip to the Building and running section.
Preparing the DFU-ready variant of your board
Before enabling DFU in your application, you must first add an MCUboot variant of your board.
Assuming that your board is bm_nrf54l15dk and using the S115 SoftDevice with the existing board variant name of bm_nrf54l15dk/nrf54l15/cpuapp/s115_softdevice, then you can use the bm_nrf54l15dk/nrf54l15/cpuapp/s115_softdevice/mcuboot board variant to enable DFU support in your application.
This board target will always enable DFU support when it is used to build the application.
Go to the board directory.
Edit the
board.ymlfile to define the new board variant and flash the runner configuration:board: name: bm_nrf54l15dk full_name: Bare Metal nRF54L15 DK vendor: nordic socs: - name: nrf54l15 variants: - name: s115_softdevice cpucluster: cpuapp variants: - name: mcuboot runners: run_once: '--recover': - runners: - nrfjprog - nrfutil run: first groups: - boards: - bm_nrf54l15dk/nrf54l15/cpuapp - bm_nrf54l15dk/nrf54l15/cpuapp/s115_softdevice - bm_nrf54l15dk/nrf54l15/cpuapp/s115_softdevice/mcuboot '--erase': - runners: - nrfjprog - jlink - nrfutil run: first groups: - boards: - bm_nrf54l15dk/nrf54l15/cpuapp - bm_nrf54l15dk/nrf54l15/cpuapp/s115_softdevice - bm_nrf54l15dk/nrf54l15/cpuapp/s115_softdevice/mcuboot '--reset': - runners: - nrfjprog - jlink - nrfutil run: last groups: - boards: - bm_nrf54l15dk/nrf54l15/cpuapp - bm_nrf54l15dk/nrf54l15/cpuapp/s115_softdevice - bm_nrf54l15dk/nrf54l15/cpuapp/s115_softdevice/mcuboot
Copy the existing SoftDevice board variant files for the new board variant:
bm_nrf54l15dk_nrf54l15_cpuapp_s115_softdevice.dts->bm_nrf54l15dk_nrf54l15_cpuapp_s115_softdevice_mcuboot.dtsbm_nrf54l15dk_nrf54l15_cpuapp_s115_softdevice.yaml->bm_nrf54l15dk_nrf54l15_cpuapp_s115_softdevice_mcuboot.yamlbm_nrf54l15dk_nrf54l15_cpuapp_s115_softdevice_defconfig->bm_nrf54l15dk_nrf54l15_cpuapp_s115_softdevice_mcuboot_defconfig
Edit the
bm_nrf54l15dk_nrf54l15_cpuapp_s115_softdevice_mcuboot.dtsfile to add the partitions used for MCUboot and ensure that the chosen node is set toslot0_partition:/ { chosen { zephyr,code-partition = &slot0_partition; }; }; ... &cpuapp_rram { status = "okay"; partitions { compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; boot_partition: partition@0 { label = "boot"; reg = <0x00000000 DT_SIZE_K(32)>; }; storage_partition: partition@8000 { compatible = "fixed-subpartitions"; label = "storage"; reg = <0x00008000 DT_SIZE_K(8)>; ranges = <0x0 0x8000 DT_SIZE_K(8)>; #address-cells = <1>; #size-cells = <1>; storage0_partition: partition@0 { label = "storage0"; reg = <0x00000000 DT_SIZE_K(4)>; }; storage1_partition: partition@1000 { label = "storage1"; reg = <0x00001000 DT_SIZE_K(4)>; }; }; slot0_partition: partition@a000 { label = "slot0"; reg = <0x0000a000 DT_SIZE_K(1290)>; }; slot1_partition: partition@14c800 { label = "slot1"; reg = <0x0014c800 DT_SIZE_K(64)>; }; softdevice_partition: partition@15c800 { label = "softdevice"; reg = <0x0015c800 (DT_SIZE_K(129) + 0x200)>; }; metadata_partition: partition@17ce00 { label = "metadata"; reg = <0x0017ce00 0x200>; }; }; };
Edit the
bm_nrf54l15dk_nrf54l15_cpuapp_s115_softdevice_mcuboot.yamlfile to set the name and flash size:identifier: bm_nrf54l15dk/nrf54l15/cpuapp/s115_softdevice/mcuboot name: Bare_Metal-nRF54L15-DK-nRF54L15-Application-S115-SoftDevice-MCUboot type: mcu arch: arm toolchain: - gnuarmemb - xtools - zephyr sysbuild: true ram: 238 flash: 1298
Add a
Kconfig.defconfigfile with the following:config ROM_START_OFFSET default 0x800 if BOOTLOADER_MCUBOOT
Edit the
Kconfig.sysbuildfile with the following:if BOARD_BM_NRF54L15DK_NRF54L15_CPUAPP_S115_SOFTDEVICE_MCUBOOT choice BM_BOOTLOADER default BM_BOOTLOADER_MCUBOOT endchoice choice SOFTDEVICE_SELECTION default SOFTDEVICE_S115 endchoice choice BM_FIRMWARE_LOADER default BM_FIRMWARE_LOADER_BT_MCUMGR endchoice endif # BOARD_BM_NRF54L15DK_NRF54L15_CPUAPP_S115_SOFTDEVICE_MCUBOOT
Edit the
Kconfig.bm_nrf54l15dkfile with the following:config BOARD_BM_NRF54L15DK select SOC_NRF54L15_CPUAPP if BOARD_BM_NRF54L15DK_NRF54L15_CPUAPP_S115_SOFTDEVICE || BOARD_BM_NRF54L15DK_NRF54L15_CPUAPP_S115_SOFTDEVICE_MCUBOOT
Ensure that
BOARD_PIN_BTN_0is defined in theinclude/board-config.hfile:#define GPIO_ACTIVE_HIGH 1 #ifndef BOARD_PIN_BTN_0 #define BOARD_PIN_BTN_0 NRF_PIN_PORT_TO_PIN_NUMBER(13, 1) #endif
Building and running
Build an application using the new board target and with the desired option from Firmware loader set, and flash it to your device.
To enter the firmware loader mode, hold down Button 0 and press the reset button.
The device will be advertising with the name
nRF_BM_MCUmgrdisplayed on the terminal output.Transfer the
<build_dir>/installer_softdevice_firmware_loader.binand<build_dir>/<app_name>/zephyr/zephyr.signed.binfiles to your mobile device (see Output build files (image files) for details on output files)Open the nRF Device Manager application on your mobile device.
Select the
nRF_BM_MCUmgrnamed-device (or other name if the name has been changed) from the list.Tap the Image tab at the bottom to move to the image management tab.
Under Image upgrade select the update file to load:
Choose
installer_softdevice_firmware_loader.binto update the Softdevice and firmware loader images, this is only needed if the SoftDevice or firmware loader images have been updated, this image should be loaded first if it is needed.Choose
zephyr.signed.binto load the application update.
Tap the Start button, then select the Upload only (no revert) option to begin the firmware update process.
The mobile device will connect and load the firmware update to the device.
Once completed, reboot the device. If the installer image was loaded, then it will apply the updates and reboot into firmware loader mode automatically and allow for loading the application firmware update using the same process. If an application update was loaded, then the new application will begin executing.
Signing keys
When building with an MCUboot board variant, it will use a default dummy MCUboot signing key which should not be used in production, see Bootloader keys for details on how to generate and use a custom signing key when building an application.
DFU samples
Any sample can be built for an MCUboot-enabled board target to add DFU support in.
Applications can refer to the samples at nrf-bm/samples/boot/mcuboot_recovery_entry for a method to enter firmware loader mode by using the Bluetooth Low Energy® MCUmgr service, or nrf-bm/samples/boot/mcuboot_recovery_retention for how to reboot into firmware loader mode in a custom way from the user application.
These samples demonstrate dummy buttonless entry to the firmware loader, allowing new firmware or installer updates to be loaded over Bluetooth Low Energy® using MCUmgr.