Exploring the benefits of MCUboot's compressed image support

MCUboots compressed image support in nRF Connect SDK v2.8.0

The MCUboot compressed image support, introduced in nRF Connect SDK v2.8.0, offers a significant advancement for developers working with non-volatile memory constraints. This feature frees up a substantial portion of non-volatile memory that can be used for additional application features or internal storage.

This blog post delves into how this compression works, the current support status for various SoCs, and provides a detailed guide on how to implement and use this feature in your projects. Whether you're dealing with Flash, RRAM, or other types of non-volatile memory, this update could be a game-changer for managing firmware updates and optimizing memory usage in your embedded applications.

Overview

MCUboot image compression is a feature introduced in nRF Connect SDK v2.8.0 that provides additional non-volatile memory for applications when using MCUboot for DFU/FOTA. This feature allows the secondary slot (DFU slot) to be approximately 70% the size of the primary slot (application slot), freeing up additional memory that can be used by the application. If you want to learn more about MCUboot and DFU/FOTA, we recommend checking out Lesson 8 in the nRF Connect SDK Intermediate course.

Compressed vs Uncompressed Firmware with MCUboot

How it works

When performing a DFU/FOTA using MCUboot, a DFU partition (also known as slot 1 or the secondary partition) is required to store the newly received image. Before the introduction of the image compression feature, the DFU partition had to be the same size as the application partition (also referred to as slot 0 or the primary partition).

The illustration below depicts a conventional DFU/FOTA process with MCUboot. The DFU partition is highlighted in red, while the application partition is shown in green.

 Dual slot DFU wiith MCUboot

In some situations, this can be an issue if you are constrained on non-volatile memory and would like to have more internal non-volatile memory for your application (for new features, internal storage, etc..) 

In that case, we have good news for you in nRF Connect SDK v2.8.0! The symmetric partition size for the DFU partition and the application partition is no longer a requirement when using the new MCUboot image compression feature which allows you to define the DFU partition asymmetrically to the application partition, for example as ~70 % of the size , giving you a free ~30 % non-volatile memory boost that you can use for your application needs.

When this feature is enabled, processes occur both during the build phase and at runtime on the firmware side in MCUboot.

In your development environment, the nRF Compression library is utilized to compress the application image during the build process. The library has support for LZMA (NRF_COMPRESS_LZMA) version 1 and 2, with ARM thumb filter (NRF_COMPRESS_ARM_THUMB). The compression rate varies depending on the application size; larger applications typically achieve higher compression rates. The build system then generates a compressed image.

On the firmware side, when a compressed image is received, MCUboot decompresses the image on RAM after a reset. It ensures that the decompressed size matches the expected size, checks the hash, verifies the image's signature (if enabled) and ensures that the decompressed data is valid,  this is all done before copying the new image to the primary slot.

Support status

The feature is currently in an experimental state, and it supports the following SoCs: nRF54L15, nRF5340, and nRF52840.

How to use 

We will now demonstrate how to add this feature to a Bluetooth LE sample. We will use the Bluetooth LE LED Button Service sample (peripheral_lbs). Keep in mind that the feature can also be used with other wireless technologies (e.g., Matter) and is not restricted to Bluetooth LE only. We will demonstrate how to use this feature on the nRF54L15 DK. You can also test this feature with the nRF52840 DK or the nRF5340 DK; the main difference is step 4.

1. Create a new application based on the peripheral_lbs sample

Open nRF Connect for VS Code, from the Welcome View, select Create a new application ->  Copy a sample - > nRF Connect SDK v2.8.0 -> Bluetooth LE LED Button Service.

Store the newly created sample somewhere close to your root directory.

2. Enable MCUboot and the MCUboot compressed image support feature

This is done by adding a Sysbuild configuration file (sysbuild.conf) in the application root directory.

Switch to the Explorer view in VS Code, create a new file called sysbuild.conf, and add the following lines to it.

SB_CONFIG_BOOTLOADER_MCUBOOT=y
SB_CONFIG_MCUBOOT_MODE_OVERWRITE_ONLY=y
SB_CONFIG_MCUBOOT_COMPRESSED_IMAGE_SUPPORT=y

As shown in the screenshot below:

Please remember to use your own key to sign images that go to production. The above code configuration uses the default key stored in the SDK folder, which is accessible to all. 

3. Enable FOTA/DFU over Bluetooth LE

To enable firmware updates to be loaded to the device using Bluetooth LE, the prj.conf file of the application must be modified to include the following options. Add the following Kconfig symbols to the end of the file. 

CONFIG_BT_BUF_ACL_TX_SIZE=251
CONFIG_BT_BUF_ACL_RX_SIZE=502
CONFIG_BT_L2CAP_TX_MTU=498
CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
CONFIG_MCUMGR=y
CONFIG_MCUMGR_TRANSPORT_BT=y
CONFIG_MCUMGR_TRANSPORT_BT_REASSEMBLY=y
CONFIG_MCUMGR_TRANSPORT_BT_CONN_PARAM_CONTROL=y
CONFIG_MCUMGR_GRP_OS_MCUMGR_PARAMS=y
CONFIG_MCUMGR_GRP_OS_BOOTLOADER_INFO=y
CONFIG_MCUMGR_GRP_OS=y
CONFIG_MCUMGR_GRP_IMG=y
CONFIG_NET_BUF=y
CONFIG_ZCBOR=y
CONFIG_STREAM_FLASH=y
CONFIG_STREAM_FLASH_ERASE=y
CONFIG_IMG_MANAGER=y
CONFIG_IMG_ERASE_PROGRESSIVELY=y

Alternatively, you can use a single Kconfig symbol CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU=y (suitable for development/testing) instead of all the Kconfig symbols above. 

4. Add the static partition manager file

A static partition manager file needs to be created which has the various partitions defined for the application including the asymmetrical partitions. The following static partition manager partitioning is taken from the nRF Connect SDK MCUboot compressed update sample for the nRF54L15 and uses only internal RRAM with the primary slot being 764KiB and the secondary slot being 536KiB (allowing for updates that are up to 70% of the size of the primary slot). This file can be named pm_static_nrf54l15dk_nrf54l15_cpuapp.yml and placed in the root directory of the application.

Copy the file from here and paste it into your application root directory. This file is for the nRF54L15 DK. If you are using the nRF52840 DK or the nRF5340 DK, make sure to copy the right file from the sample folder(SDK Path\nrf\samples\nrf_compress\mcuboot_update).

With this, we have made the necessary modifications in the code to start testing the feature. 

5. Build the application

Switch to the nRF Connect extension; in the APPLICATIONS view, click on Add build configuration and build for the nrf54l15dk/nrf54l15/cpuapp. Leave the default options as they are, which enables Sysbuild, which is needed for this feature.

Examine the build log, a key information to look for here is the compressed image size as shown in the screenshot below:

The output above shows that the build system compressed the application firmware quite well, with a compression percentage of about 42%.

6. Flash the application to your development kit

From the ACTIONS view, click on Flash to flash the firmware onto your development kit.

7. Open serial terminal 

Open the serial terminal on your board from the CONNECTED DEVICES view to see your board's log output.

*** Booting MCUboot v2.1.0-dev-4594a8693738 ***
*** Using nRF Connect SDK v2.8.0-a2386bfc8401 ***
*** Using Zephyr OS v3.7.99-0bc3393fb112 ***
I: Starting bootloader
I: Image index: 0, Swap type: none
I: Bootloader chainload address offset: 0x10000
*** Booting My Application v2.8.0-ba791918d3c1 ***
*** Using nRF Connect SDK v2.8.0-a2386bfc8401 ***
*** Using Zephyr OS v3.7.99-0bc3393fb112 ***
Starting Bluetooth Peripheral LBS example
I: 8 Sectors of 4096 bytes
I: alloc wra: 0, fc0
I: data wra: 0, 0
I: SoftDevice Controller build revision: 
I: fe 2c f9 6a 7f 36 22 2e |.,.j.6".
I: a0 79 c0 40 be 2c 03 20 |.y.@.,. 
I: 40 c2 f3 32             |@..2    
I: HW Platform: Nordic Semiconductor (0x0002)
I: HW Variant: nRF54Lx (0x0005)
I: Firmware: Standard Bluetooth controller (0x00) Version 254.63788 Build 573996906
I: No ID address. App must call settings_load()
Bluetooth initialized
I: Identity: D5:DE:56:9A:D9:88 (random)
I: HCI: version 6.0 (0x0e) revision 0x304e, manufacturer 0x0059
I: LMP: version 6.0 (0x0e) subver 0x304e
Advertising successfully started

You can press the reset button on your board, to see the log from the start. 

8. Create a new image for testing

The existing application can be modified to demonstrate testing the update features of compressed MCUboot images, for example by modifying the src/main.c file to print an extra message when the application starts advertising. Add printk("(Compressed image update running)\n"); above the advertising message.

    printk("(Compressed image update running)\n");
    printk("Advertising successfully started\n");

Also, change the run state LED from LED1 to LED4 

#define RUN_STATUS_LED          DK_LED4

These changes help us recognize the new firmware running easily.

9. Build the new image

This application can then be built as the previous version was. The build system will automatically compress the firmware update when it is generated, and this file will be included in the build/dfu_application.zip file, which can be used as with non-compressed firmware update zip files. DO NOT flash it using the debugger; instead, send the dfu_application.zip file to your mobile device.

10. Perform FOTA/DFU over Bluetooth LE with the compressed image 

On your mobile device, open the nRF Connect for Mobile app; from the SCANNER tab, connect to the device “Nordic_LBS” once the connection is established. Press on the three dots at the top right corner and select Bond.

Bond with BLE device

You will be prompted to enter a passkey. 

The passkey will be printed on your serial terminal as a 6-digit number.

Passkey for XX:XX:XX:XX:XX:XX (random): XXXXXX

This helps authenticate and encrypt the connection. 

Once the pairing process is completed, Press on the three dots at the top right corner and select DFU. Then select the dfu_application.zip. Finally, select Test and Confirm and press OK.

The transfer process will start and will take a few seconds to finish.

DFU over BLE  

The new image will be first uploaded to the DFU slot; once the transfer is complete, an automatic reset is triggered, and MCUboot will start decompressing and validating the new image. Once the validation is completed successfully, MCUboot will move the new decompressed image to the primary slot (non-revertible) and the new image will boot. You should now notice that the new image is running. Notice that LED4 (PCB labeled LED3 on the nRF54L15 DK) represents the run state instead of LED1 (PCB labeled LED0 on the nRF54L15 DK), and the new log message " (Compressed image update running)" is printed on the terminal. 

I: Image index: 0, Swap type: none
I: Image index: 0, Swap type: none
I: Image index: 0, Swap type: none
I: Image index: 0, Swap type: none
I: Image index: 0, Swap type: test
*** Booting MCUboot v2.1.0-dev-4594a8693738 ***
*** Using nRF Connect SDK v2.8.0-a2386bfc8401 ***
*** Using Zephyr OS v3.7.99-0bc3393fb112 ***
I: Starting bootloader
I: Image index: 0, Swap type: test
I: Image 0 upgrade secondary slot -> primary slot
I: Erasing the primary slot
I: Image 0 copying the secondary slot to the primary slot: 0x37370 bytes
I: Bootloader chainload address offset: 0x10000
*** Booting My Application v2.9.0-ba791918d3c1 ***
*** Using nRF Connect SDK v2.8.0-a2386bfc8401 ***
*** Using Zephyr OS v3.7.99-0bc3393fb112 ***
Starting Bluetooth Peripheral LBS example
I: 8 Sectors of 4096 bytes
I: alloc wra: 0, ef0
I: data wra: 0, c0
I: SoftDevice Controller build revision: 
I: fe 2c f9 6a 7f 36 22 2e |.,.j.6".
I: a0 79 c0 40 be 2c 03 20 |.y.@.,. 
I: 40 c2 f3 32             |@..2    
I: HW Platform: Nordic Semiconductor (0x0002)
I: HW Variant: nRF54Lx (0x0005)
I: Firmware: Standard Bluetooth controller (0x00) Version 254.63788 Build 573996906
I: No ID address. App must call settings_load()
Bluetooth initialized
I: Identity: D5:DE:56:9A:D9:88 (random)
I: HCI: version 6.0 (0x0e) revision 0x304e, manufacturer 0x0059
I: LMP: version 6.0 (0x0e) subver 0x304e
(Compressed image update running)
Advertising successfully started
Connected
Security changed: 64:5D:F4:DB:C6:9C (public) level 4

Note: You could also use the nRF Connect Device Manager mobile app for DFU/FOTA over Bluetooth LE. 

Restrictions

There are currently some restrictions when using compressed firmware updates with MCUboot:

  • Only one image is supported (this means network core updates on nRF5340 or MCUboot updates are not supported).
  • Encrypted firmware updates are not supported.
  • MCUboot must be in upgrade-only mode, meaning that firmware version revert is not supported.
  • Sysbuild and the Partition Manager are mandatory for this feature. 

Read more