A/B with MCUboot
The A/B with MCUboot sample demonstrates how to configure the application for updates using the A/B method using MCUboot. It also includes an example to perform a device health check before confirming the image after the update.
You can update the sample using the Simple Management Protocol (SMP) with UART or Bluetooth® Low Energy.
Requirements
The sample supports the following development kits:
Hardware platforms |
PCA |
Board name |
|
|---|---|---|---|
nRF7120 DK |
nrf7120dk |
|
|
PCA10156 |
|
||
PCA10175 |
|
You need the nRF Device Manager app for update over Bluetooth Low Energy:
Overview
This sample demonstrates firmware update using the A/B method. This method allows two copies of the application in the NVM memory. It is possible to switch between these copies without performing a swap, which significantly reduces time of device’s unavailability during the update. The switch between images can be triggered by the application or, for example, by a hardware button.
This sample implements an SMP server. SMP is a basic transfer encoding used with the MCUmgr management protocol. For more information about MCUmgr and SMP, see Device Management.
The sample supports the following MCUmgr transports by default:
Bluetooth
Serial (UART)
A/B functionality
When the A/B functionality is used, the device has two slots for the application: slot A and slot B. The slots are equivalent, and the device can boot from either of them. In the case of MCUboot, this is achieved by using the Direct-xip feature. Thus, note that the terms slot 0, primary slot, slot A and slot 1, secondary slot, slot B are used interchangeably throughout the documentation. This configuration allows a background update of the non-active slot while the application runs from the active slot. After the update is complete, the device can quickly switch to the updated slot on the next reboot.
The following conditions decide which slot will be booted (active) on the next reboot:
If one of the slots is not valid, the other slot is selected as active.
If both slots are valid, the slot marked as “preferred” is selected as active.
If both slots are valid and none is marked as “preferred,” the slot with the higher version number is selected as active.
If none of the above conditions is met, slot A is selected as active.
You can set the preferred slot using the boot_request_set_preferred_slot() function.
If the CONFIG_NRF_MCUBOOT_BOOT_REQUEST_PREFERENCE_KEEP option is enabled, the slot preference remains persistent across reboots.
Otherwise, the slot preference is cleared on reboot.
To enable the persistence of a preferred slot, define a backup region for the bootloader request area by using the nrf,bootloader-request-backup chosen node in the devicetree.
Identifying the active slot
If the project uses the Partition Manager, the currently running slot can be identified by checking if CONFIG_NCS_IS_VARIANT_IMAGE is defined.
If it is defined, the application is running from slot B.
Otherwise, it is running from slot A.
If the project does not use the Partition Manager (a configuration currently only supported on the nRF54H20), the currently running slot can be identified by comparing the address pointed zephyr,code-partition to specific node addresses defined in the device tree. The following node partitions are used by default:
cpuapp_slot0_partition- Application core, slot Acpuapp_slot1_partition- Application core, slot Bcpurad_slot0_partition- Radio core, slot Acpurad_slot1_partition- Radio core, slot B
For example, verifying that the application is running from slot A can be done by using the following macro:
#define IS_RUNNING_FROM_SLOT_A \
(PARTITION_NODE_OFFSET(DT_CHOSEN(zephyr_code_partition)) == \
PARTITION_OFFSET(cpuapp_slot0_partition))
Build files
When building for the nRF54H20, the merge slot feature is used if Direct-xip is enabled. This means that, for both slot A and slot B, the application image and the radio image are merged and treated as a single image by MCUboot. In this case, the following files should be sent to the device when performing an update:
build/zephyr_secondary_app.merged.bin- Contains the slot B image. This file should be uploaded to the secondary slot when the device is running from slot A.build/zephyr.merged.bin- Contains the slot A image. This file should be uploaded to the primary slot when the device is running from slot B.
If building on other supported platforms, where there is no separate radio core, only the application core is updated. In this case, the following MCUboot files for the application image are used:
build/mcuboot_secondary_app/zephyr/zephyr.signed.bin- Contains the slot B image. This file should be uploaded to the secondary slot when the device is running from slot A.build/ab/zephyr/zephyr.signed.bin- Contains the slot A image. This file should be uploaded to the primary slot when the device is running from slot B.
Device health check
This sample implements a device health check mechanism to ensure the firmware works correctly after an update.
The radio image is verified by checking whether the Bluetooth stack initializes successfully using the bt_is_ready function.
The application image is verified by checking the value of the CONFIG_EMULATE_APP_HEALTH_CHECK_FAILURE option.
If this option is enabled, the application image is treated as faulty and the self-test fails.
If either verification step fails, the application does not confirm the image. You can still confirm the image manually using the SMP command, which overrides the result of the health check.
The implementation of these checks is located in src/ab_utils.c.
User interface
- LED 0:
This LED indicates that the application is running from slot A. It is controlled as active low, meaning it will turn on once the application is booted and blinks (turns off) in short intervals. The number of short blinks is configurable using the
CONFIG_N_BLINKSKconfig option. It will remain off if the application is running from slot B.- LED 1:
This LED indicates that the application is running from slot B. It is controlled as active low, meaning it will turn on once the application is booted and blinks (turns off) in short intervals. The number of short blinks is configurable using the
CONFIG_N_BLINKSKconfig option. It will remain off if the application is running from slot A.- Button 0:
By pressing this button, the slot A will be selected as the preferred slot on the next reboot. This preference applies only to the next boot and is cleared after the subsequent reset.
- Button 1:
By pressing this button, the slot B will be selected as the preferred slot on the next reboot. This preference applies only to the next boot and is cleared after the subsequent reset.
Configuration
See Configuring and building for information about how to permanently or temporarily change the configuration.
Configuration options
Check and configure the following configuration option for the sample:
- CONFIG_N_BLINKS - The number of blinks.
This configuration option sets the number of times the LED corresponding to the currently active slot blinks (LED0 for slot A, LED1 for slot B). The default value of the option is set to
1, causing a single blink to indicate Version 1. You can increment this value to represent an update, such as set it to2to indicate Version 2.
- CONFIG_EMULATE_APP_HEALTH_CHECK_FAILURE - Enables emulation of a broken application that fails the self-test.
This configuration option emulates a broken application that does not pass the self-test.
Additional configuration
Check and configure the CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION library Kconfig option specific to the MCUboot library.
This configuration option sets the version to pass to imgtool when signing.
To ensure the updated build is preferred after a DFU, set this option to a higher version than the version currently running on the device.
Building and running
This sample can be found under samples/dfu/ab in the nRF Connect SDK folder structure.
To build the sample, follow the instructions in Building an application for your preferred building environment. See also Programming an application for programming steps and Testing and optimization for general information about testing and debugging in the nRF Connect SDK.
Note
When building repository applications in the SDK repositories, building with sysbuild is enabled by default.
If you work with out-of-tree freestanding applications, you need to manually pass the --sysbuild parameter to every build command or configure west to always use it.
Testing
To perform DFU using the nRF Connect Device Manager mobile app, complete the following steps:
Generate the DFU package by building your application with the FOTA support over Bluetooth Low Energy. You can find the generated
dfu_application.ziparchive in the build directory.Note
For each image included in the DFU-generated package, use a higher version number than your currently active firmware. Otherwise, the DFU target may reject the FOTA process due to a downgrade prevention mechanism.
Download the
dfu_application.ziparchive to your device. See Output build files (image files) for more information about the contents of update archive.Note
nRF Connect for Desktop does not currently support the FOTA process.
Use the nRF Connect Device Manager mobile app to update your device with the new firmware.
Ensure that you can access the
dfu_application.ziparchive from your phone or tablet.In the mobile app, scan and select the device to update.
Switch to the Image tab.
Tap the SELECT FILE button and select the
dfu_application.ziparchive.Tap the START button.
Note
When performing a FOTA update with the iOS app for samples using random HCI identities, ensure that the Erase application settings option is deselected before starting the procedure. Otherwise, the new image will boot with random IDs, causing communication issues between the app and the device.
Initiate the DFU process of transferring the image to the device:
If you are using an Android device, select a mode in the dialog window, and tap the START button.
If you are using an iOS device, tap the selected mode in the pop-up window.
Note
For samples using random HCI identities, the Test and Confirm mode should not be used.
Wait for the DFU to finish and then verify that the application works properly.
Instead of using the dfu_application.zip file, you can also send the appropriate binary file directly, as described in Build files.
Make sure to select the correct file based on the currently running slot.
Dependencies
This sample uses the following nRF Connect SDK library: