.. _ug_dfu: 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 :ref:`dfu_memory_partitioning` and :ref:`ug_bootloader_keys` sections. Partition Configuration *********************** The memory of your device must be partitioned appropriately to accommodate the bootloader, application, and firmware update mechanisms. |BMshort| uses Zephyr's `DTS`_ system for memory partitioning. For details on memory partitioning and related concepts, see :ref:`dfu_memory_partitioning`. 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. .. _ug_dfu_firmware_loader: 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_GPIO`` sysbuild Kconfig option to use this mode. * Using the reset pin Set the ``SB_CONFIG_BM_BOOTLOADER_MCUBOOT_FIRMWARE_LOADER_ENTRANCE_PIN_RESET`` sysbuild 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_MODE`` sysbuild 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. .. _ug_dfu_output_build_files: Output build files (image files) ******************************** When DFU is enabled in the application, the build system outputs the following files. +--------------------------------------------------------------------------------+----------------------------------------------+--------------------------------+ | File | Description | Programming scenario | +================================================================================+==============================================+================================+ | :file:`/firmware_loader/zephyr/zephyr.signed.hex` | Firmware loader image. | Programming board targets. | +--------------------------------------------------------------------------------+----------------------------------------------+ | | :file:`/mcuboot/zephyr/zephyr_signed_softdevice_flash_metadata.hex` | MCUBoot image with SoftDevice. | | +--------------------------------------------------------------------------------+----------------------------------------------+ | | :file:`//zephyr/zephyr.signed.hex` | Application image. | | +--------------------------------------------------------------------------------+----------------------------------------------+--------------------------------+ | :file:`/production.hex` | Production hex file, containing: MCUboot, | Production device programming. | | | firmware loader, SoftDevice and main | | | | application images. | | +--------------------------------------------------------------------------------+----------------------------------------------+--------------------------------+ | :file:`/installer_softdevice_firmware_loader.bin` | Installer Update image (DFU) with SoftDevice | DFU process for board targets. | | | and firmware loader updates. | | +--------------------------------------------------------------------------------+----------------------------------------------+ | | :file:`//zephyr/zephyr.signed.bin` | Application Update image (DFU). | | +--------------------------------------------------------------------------------+----------------------------------------------+--------------------------------+ Running DFU in your application ******************************* The following is the workflow for testing the DFU mechanism on an application developed with |BMshort|. .. note:: The preparation below here describes how to add a MCUboot board variant to a custom board, for |BMshort| there already are MCUboot board variants for the ``bm_nrf54l15dk`` board: * ``bm_nrf54l15dk/nrf54l05/cpuapp/s115_softdevice/mcuboot`` for nRF54L15 (emulating nRF54L05) with S115 softdevice * ``bm_nrf54l15dk/nrf54l10/cpuapp/s115_softdevice/mcuboot`` for nRF54L15 (emulating nRF54L10) with S115 softdevice * ``bm_nrf54l15dk/nrf54l15/cpuapp/s115_softdevice/mcuboot`` for nRF54L15 with S115 softdevice To test DFU with one of these default board targets, skip to the :ref:`ug_dfu_building_running` section. .. _ug_dfu_preparing_dfu_board: 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. 1. Go to the board directory. #. Edit the :file:`board.yml` file to define the new board variant and flash the runner configuration: .. code-block:: yaml 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: * :file:`bm_nrf54l15dk_nrf54l15_cpuapp_s115_softdevice.dts` -> :file:`bm_nrf54l15dk_nrf54l15_cpuapp_s115_softdevice_mcuboot.dts` * :file:`bm_nrf54l15dk_nrf54l15_cpuapp_s115_softdevice.yaml` -> :file:`bm_nrf54l15dk_nrf54l15_cpuapp_s115_softdevice_mcuboot.yaml` * :file:`bm_nrf54l15dk_nrf54l15_cpuapp_s115_softdevice_defconfig` -> :file:`bm_nrf54l15dk_nrf54l15_cpuapp_s115_softdevice_mcuboot_defconfig` #. Edit the :file:`bm_nrf54l15dk_nrf54l15_cpuapp_s115_softdevice_mcuboot.dts` file to add the partitions used for MCUboot and ensure that the chosen node is set to ``slot0_partition``: .. code-block:: devicetree / { 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 :file:`bm_nrf54l15dk_nrf54l15_cpuapp_s115_softdevice_mcuboot.yaml` file to set the name and flash size: .. code-block:: yaml 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 :file:`Kconfig.defconfig` file with the following: .. code-block:: kconfig config ROM_START_OFFSET default 0x800 if BOOTLOADER_MCUBOOT #. Edit the :file:`Kconfig.sysbuild` file with the following: .. code-block:: kconfig 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 :file:`Kconfig.bm_nrf54l15dk` file with the following: .. code-block:: kconfig 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_0`` is defined in the :file:`include/board-config.h` file: .. code-block:: c #define GPIO_ACTIVE_HIGH 1 #ifndef BOARD_PIN_BTN_0 #define BOARD_PIN_BTN_0 NRF_PIN_PORT_TO_PIN_NUMBER(13, 1) #endif .. _ug_dfu_building_running: Building and running ==================== 1. Build an application using the new board target and with the desired option from :ref:`ug_dfu_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_MCUmgr`` displayed on the terminal output. #. Transfer the :file:`/installer_softdevice_firmware_loader.bin` and :file:`//zephyr/zephyr.signed.bin` files to your mobile device (see :ref:`ug_dfu_output_build_files` for details on output files) #. Open the nRF Device Manager application on your mobile device. #. Select the ``nRF_BM_MCUmgr`` named-device (or other name if the name has been changed) from the list. #. Tap the :guilabel:`Image` tab at the bottom to move to the image management tab. #. Under :guilabel:`Image upgrade` select the update file to load: * Choose :file:`installer_softdevice_firmware_loader.bin` to 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 :file:`zephyr.signed.bin` to load the application update. #. Tap the :guilabel:`Start` button, then select the :guilabel:`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 :ref:`ug_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 :file:`nrf-bm/samples/boot/mcuboot_recovery_entry` for a method to enter firmware loader mode by using the Bluetooth Low Energy® MCUmgr service, or :file:`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.