This exercise is not yet supported in nRF Connect SDK v2.7.0 or v2.8.0. The support is ongoing.
Apologies for any inconvenience.
In this exercise, we will learn how to do DFU over Bluetooth Low Energy. This is often known as Firmware Over The Air (FOTA). We will base the exercise on the Bluetooth: Peripheral LBS sample. First, we will enable MCUboot and FOTA in our sample. Then, we will go through how to update the device from a mobile phone.
In Zephyr, a set of configurations are needed to enable FOTA. An example of how to set this up can be seen in the SMP Server sample. However, the nRF Connect SDK includes the option CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU
, which sets all needed configurations for us. This option makes it easier for us to enable FOTA, so we will use that.
This configuration is named CONFIG_NCS_SAMPLE… as it makes some assumptions about the project. For your custom project, I recommend that you look at what configurations CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU
set for you, and include the ones from there you need instead.
Documentation on enabling FOTA for each of our products can be seen under Device configuration guides, for example, developing with nRF52 Series and FOTA over Bluetooth Low Energy.
For this exercise, we can use any development kit based on the nRF52 series or the nRF5340 DK. For the nRF5340 DK, we will only update the application core in this exercise. Updating the network core will be covered in later exercises.
Open the code base of the exercise by navigating to Create a new application in the nRF Connect for VS Code extension, select Copy a sample, and search for Lesson 8 – Exercise 3.
Alternatively, in the GitHub repository for this course, go to the base code for this exercise, found in l8/l8_e3
.
1. Test the sample out-of-box.
First, it is always a good idea to test the example as is, to verify that it works from the start.
Build and flash the exercise code base, which is just a copy of the Bluetooth: Peripheral LBS sample. Verify that it works as expected. The Peripheral LBS is also covered in-depth in the Bluetooth Low Energy Fundamentals course.
2. Add MCUboot and FOTA over Bluetooth Low Energy to the application.
Enable MCUboot and FOTA by adding the following lines to the prj.conf
file.
CONFIG_BOOTLOADER_MCUBOOT=y
CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU=y
Kconfig3. Build and flash the application.
4. Add a print and rebuild the application.
Next, add a print somewhere to the main function, and build the project again.
This is to generate a new file for DFU, with something different which we can observe.
5. Update the firmware using nRF Connect Device Manager.
5.1 To perform DFU, we will use the nRF Connect Device Manager app for mobile. Install this on your phone. (As an alternative for testing this with a PC, mcumgr on Linux can be used for FOTA over Bluetooth Low Energy)
5.2 When opening the Device Manager app, it will not find any devices. This is because the app by default filters for an SMP Service UUID. We could add this to the advertising or scan response of the sample, as covered in the Bluetooth Low Energy Fundamentals on Advertising. In the field, your DFU Server would likely filter for your devices UUIDs rather than a generic SMP UUID. Either way, we will take a shortcut here and just disable the filter, as seen in the screenshot below. Uncheck the checkbox.
5.3 After unchecking the box, select the Peripheral LBS sample to connect to. Observe the features listed in the menubar at the bottom. These are SMP Services. We will use the second tab: Image. This tab should look like the screenshot below.
5.4 The first step is to move our new firmware image to the phone. This would be the same file used in the previous exercises: build/zephyr/app_update.bin. Use your preferred method to transfer this file from your computer to the phone.
5.5 Click “Select file” and select app_update.bin, and then press “Start”. You learned about “test” and “confirm” previously in this course. The “Test & Confirm” option first tags the image with “test”, and after the swap, the app will reconnect to the chip and confirm the image before it reverts. It is up to you which choice you use here.
Docs on how to do this can be seen in Developing with nRF5340 DK: Simultaneous multi-image DFU.
6. In this step, we will learn how to enable simultaneous updates for both the application core and the network core on the nRF5340 over Bluetooth Low Energy.
6.1 To do this, we need to configure the MCUboot child image.
Create the following file child_image/mcuboot.conf
and input the code snippet below:
# STEP 6.2 - Enable QSPI drivers for external flash
# STEP 6.3 - Add relevant configurations
Kconfig6.2 From the documentation, we must create some partitions. If we enable external flash in the project, these partitions will be automatically created. For simultaneous updates, we most often want to use external flash either way, to give the application more flash to work with, so we will enable external flash here. We will use the partition manager to enable external flash. There are several ways to set devicetree overlays. You can choose whatever fits you best, but for this exercise we will just use app.overlay
, added directly to the project directory.
Now we have enabled external flash for the application. However, child images must be configured separately, so we also need to add the partition manager overlay into child_image/mcuboot.overlay. In addition to this, the MCUboot does not have QSPI drivers enabled by default. To enable these, add CONFIG_NORDIC_QSPI_NOR=y
to child_image/mcuboot.conf
. Also, since the slot sizes become bigger, we must increase CONFIG_BOOT_MAX_IMG_SECTORS
, for example to 256. So for child_image/mcuboot.conf
:
CONFIG_NORDIC_QSPI_NOR=y
CONFIG_BOOT_MAX_IMG_SECTORS=256
Kconfig6.3 Now we add the relevant configurations to child_image/mcuboot.conf
.
These are found from Developing with nRF5340 DK: Simultaneous multi-image DFU and CONFIG_NRF53_MULTI_IMAGE_UPDATE
dependencies:
# Logging
CONFIG_LOG=y
CONFIG_MCUBOOT_LOG_LEVEL_WRN=y
# Enable simultaenous multi-core updates
CONFIG_NRF53_MULTI_IMAGE_UPDATE=y
CONFIG_UPDATEABLE_IMAGE_NUMBER=2
CONFIG_BOOT_UPGRADE_ONLY=y
CONFIG_PCD_APP=y
# Dependencies for CONFIG_NRF53_MULTI_IMAGE_UPDATE
CONFIG_FLASH=y
CONFIG_FLASH_SIMULATOR=y
CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y
CONFIG_FLASH_SIMULATOR_STATS=n
Kconfig6.4 Enable updates for the network core.
Finally, we must set the following configurations for the application, in the prj.conf
file
CONFIG_NRF53_UPGRADE_NETWORK_CORE=y
CONFIG_UPDATEABLE_IMAGE_NUMBER=2
Kconfig7. Build and flash the application to the nRF5340 DK.
Make sure to build for the nrf5340dk_nrf5340_cpuapp
build target.
8. Update both the application core and the network core image on the device.
We now need to change both our application core image and our network core image.
8.1 For the application core, add a print somewhere to the main function, and build the project again. This is to generate a new file for DFU, with something different which we can observe.
8.2 For the network core, enable logging so we can see the change after FOTA:
Add the following to child_image/hci_rpmsg.conf
to enable logging, and remove the line that is there already (CONFIG_SERIAL=n
)
Starting from nRF Connect SDK version 2.6.0, the configruation file for the network core on the nRF5340 DK is named hci_ipc.conf
instead of hci_rpmsg.conf
. If you are using nRF Connect SDK v2.6.0 or above, populate the hci_ipc.conf
file , if you are using nRF Connect SDK < 2.6.0, populate the hci_rpmsg.conf
file.
CONFIG_SERIAL=y
CONFIG_LOG=y
CONFIG_LOG_DEFAULT_LEVEL=4
CONFIG_MAIN_STACK_SIZE=2048
Kconfig9. Build the project again, and to update both cores, follow the same procedure as in step 5. Install and configure the nRF Connect Device Manager app. but with dfu_application.zip
instead of app_update.bin
.
The solution for this exercise can be found in the GitHub repository, l8/l8_e3_sol
.