Feedback
Feedback

If you are having issues with the exercises, please create a ticket on DevZone: devzone.nordicsemi.com
Click or drag files to this area to upload. You can upload up to 2 files.

Exercise 1 – DFU over UART

In this exercise, we will learn how to do DFU over UART . We will first enable Serial Recovery and then add DFU in the application. Both these can be active at the same time. After all, the bootloader does not know anything about the application.

UART0 on our development kits are routed to the debugger chip and exposed to the connected PC as a VCOM port. Therefore, we do not have to connect anything extra to the DK to test DFU over UART.

Exercise prerequisites

To send the firmware updates over UART, we will use the command line tool mcumgr-cli. You can install this using:

go install github.com/apache/mynewt-mcumgr-cli/mcumgr@latest

You might have to install Go to install mcumgr-cli. See https://go.dev/doc/install for how to install Go.

Note

You will need to add mcumgr to path . For Linux , export PATH="$PATH:$HOME/go/bin" For Windows, you can add it using the Edit System system environment variables

Now we can run mcumgr from the CLI:

Prepare the DK

The DK debugger (Interface MCU)has a virtual mass storage disk. This may interfere with UART DFU transfer since the Interface MCU is also used for UART<> USB conversion, so it is recommended to disable it using the J-link Commander(Windows), or JLinkExe(Linux) :

JLinkExe -device NRF52840_XXAA -if SWD -speed 4000 -autoconnect 1 -SelectEmuBySN SEGGER_ID
J-Link>MSDDisable
Probe configured successfully.
J-Link>exit

The Development Kit must then be power-cycled for the settings to take effect. Replace SEGGER_ID with the SEGGER ID of your DK. The SEGGER ID is for the on-board debugger on the DK. Each DK has its unique SEGGER ID. The SEGGER ID is displayed in the Connected Devices View in nRF Connect for VS Code, as shown in the screenshot below. It’s also printed on the kit label.

Note that this setting remains valid even if you program another firmware onto the device.

Exercise steps

For this exercise, The base code is simply a copy of the Blinky sample. The goal here is to show you how to add MCUboot to an existing nRF Connect SDK application.

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 1.

Alternatively, in the GitHub repository for this course, go to the base code for this exercise, found in lesson8/inter_less8_exer1.

1. Enable MCUboot in prj.conf

CONFIG_BOOTLOADER_MCUBOOT=y
Kconfig

2. Enable logging for MCUboot

2.1 Create a child_image directory to configure child images.

2.2 Create a file to configure MCUboot in the child image folder and add the following comments inside mcuboot.conf

# STEP 2.3 - Enable logging for MCUboot

# STEP 3.1 - Enable Serial Recovery over UART

# STEP 3.2 - Disable UART, since Serial Recovery uses it

# STEP 3.3 - Configure boolader to use only one slot. 
# STEP 5.1 - Go back to two slots, as we need two for DFU from the app

# STEP 3.4 - Turn on a LED so we can see when Serial Recovery mode is active
Kconfig

The folder structure should now look like this:

2.3 Next, we will enable logging for MCUboot. For this, we both need to enable logs and set the log level:

CONFIG_LOG=y
CONFIG_MCUBOOT_LOG_LEVEL_INF=y
Kconfig

After this, we can build and run the sample to see it run with MCUboot. Observe logs from nRF Serial Terminal:

*** Booting nRF Connect SDK 2.6.1-3758bcbfa5cd ***
I: Starting bootloader
I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
I: Boot source: none
I: Image index: 0, Swap type: none
I: Bootloader chainload address offset: 0xc000
Terminal

We can also see the partitioning of the device, with the nRF Connect for VS Code Memory Report

Now, we have MCUboot running before the application. However, we can not yet update the application.

3. Add DFU over UART to MCUboot

Next, we will add DFU over UART to MCUboot, also known as Serial Recovery. MCUboot configuration options can be found here, and MCUboot Kconfig options specific for Serial Recovery are found here .

3.1 To enable Serial Recovery, we must set CONFIG_MCUBOOT_SERIAL and to enable transport over UART, we must set BOOT_SERIAL_UART. Since these are both for the MCUboot child image, we must set them in mcuboot.conf.

CONFIG_MCUBOOT_SERIAL=y
CONFIG_BOOT_SERIAL_UART=y
Kconfig

3.2 Since we now use UART for Serial Recovery, we must disable UART from the console from MCUboot, so this does not try to use the UART at the same time.

CONFIG_UART_CONSOLE=n
Kconfig

3.3 By default, MCUboot splits the non-volatile memory into two slots. Since we use Serial Recovery, we can use only one slot instead to get more available non-volatile memory. We can do this by setting CONFIG_SINGLE_APPLICATION_SLOT.

CONFIG_SINGLE_APPLICATION_SLOT=y
Kconfig

3.4. To indicate that MCUboot is in Serial Recovery mode, it is nice to have an indicator LED. We can enable this by setting CONFIG_MCUBOOT_INDICATION_LED.

CONFIG_MCUBOOT_INDICATION_LED=y
Kconfig

3.5 we will set which button and LED will be used before testing. This is set using a Devicetree overlay. For this, we will create the file child_image/mcuboot.overlay. Now, the folder structure will then look like this:

Add the following comment to mcuboot.overlay:

/* Step 3.5 - Configure button and LED for Serial Recovery */
Devicetree

Under it, add

/ {
  aliases {
		mcuboot-button0 = &button1;
		mcuboot-led0 = &led1;
  };
};
Devicetree

Note that the alias button1 represents the physical Button 2 on the DK. led1 alias represents the physical LED2 on the DK. Alieases and node identifiers in devicetree start from 0, while on the physical board, they start from 1.

4. Build and flash the application to your board.

Now we can test Serial Recovery. When you start the kit normally, you see LED1 blink as normal.

4.1 Now, hold button 2 while resetting the Development Kit. Instead of starting normally, the kit will now enter Serial Recovery mode. You can see this from LED2, which should be on.

4.2 While in serial recovery mode, we can use mcumgr-cli to communicate with the DK. First, we will add a configuration to mcumgr-cli:

Linux/OSX:

mcumgr conn add testDK type="serial" connstring="dev=/dev/ttyACM0,baud=115200,mtu=512"

Windows:

mcumgr conn add testDK type="serial" connstring="COM14,baud=115200,mtu=512"

Note that the port number will vary from machine to machine and DK to DK. Use the Connected Devices view in nRF Connect for VS Code to know the port of your DK.

testDK in the command above can be named whatever we want. A list of supported mcumgr-cli commands can be found here.

4.3 With this configuration, we can test listing current images on the DK:

mcumgr -c testDK image list

This should return the following:

Images:
 image=0 slot=0
    version: 0.0.0
    bootable: false
    flags: 
    hash: 59947af60569a6512f303d69047cc875efd662c5834a4990f640b96e9923ef0e
Split status: N/A (0)
Terminal

Important

If you see an error like Error: Access is denied. it means there is an application on your machine that is using that same port. Close all applications that use that port to eliminate this error message.

4.4 Before we try to upload a new firmware image to the DK, we should change something in the application, so we can verify that the new firmware image has been flashed. This can, for example be to change the delay in the blinky code. For example, change SLEEP_TIME_MS from 1000 to 100, then rebuild the code.

4.5 Now we can upload the new image firmware to the DK, using:

mcumgr -c testDK image upload build/zephyr/app_update.bin

Then this should be the result:

6.93 KiB / 42.01 KiB [====================>-------------------------------------------------------------------------------------------------------]  16.50% 3.14 KiB/s 00m11s
Terminal

4.6 After the successful upload, reset the DK to see the new image in effect:

mcumgr -c testDK reset

DFU over UART from the application

5. Add DFU over UART to the application.

Next up, we will add DFU over UART to the application. This method uses the mcumgr library.

5.1 First, we must go back to dual slots, as DFU from the application must have two slots:

CONFIG_SINGLE_APPLICATION_SLOT=n
Kconfig

5.2 Then we add mcumgr configurations and dependencies to prj.conf. We can take inspiration from the SMP Server sample to find which configurations we need. For this exercise, we can use the following:


# Step 5.2 - Enable mcumgr DFU in application
# Enable MCUMGR 
CONFIG_MCUMGR=y

# Enable MCUMGR management for both OS and Images
CONFIG_MCUMGR_GRP_OS=y
CONFIG_MCUMGR_GRP_IMG=y

# Configure MCUMGR transport to UART
CONFIG_MCUMGR_TRANSPORT_UART=y

# Dependencies
# Configure dependencies for CONFIG_MCUMGR  
CONFIG_NET_BUF=y
CONFIG_ZCBOR=y
CONFIG_CRC=y

# Configure dependencies for CONFIG_MCUMGR_GRP_IMG  
CONFIG_FLASH=y
CONFIG_IMG_MANAGER=y

# Configure dependencies for CONFIG_IMG_MANAGER  
CONFIG_STREAM_FLASH=y
CONFIG_FLASH_MAP=y

# Configure dependencies for CONFIG_MCUMGR_TRANSPORT_UART 
CONFIG_BASE64=y
Kconfig

5.3 With this, we can do DFU over UART without entering bootloader mode.
Build, flash and start the DK normally (do not hold any buttons). During operations, we can use the mcumgr-cli to list images, as before:

mcumgr -c testDK image list

Then we change the application code again, build the code and upload the new firmware image:

mcumgr -c testDK image upload build/zephyr/app_update.bin

5.4 Since we now use a dual slot configuration, the uploaded application does not automatically run. We can reset the DK now without any change. To make the application swap into primary slot, we must tag it with either “test” or “confirm”. Let’s do “test” first. First, we need to get the hash of the image:

mcumgr -c testDK image list

Will return:

Images:
 image=0 slot=0
    version: 0.0.0
    bootable: true
    flags: active confirmed
    hash: <OLD_HASH>
 image=0 slot=1
    version: 0.0.0
    bootable: true
    flags: 
    hash: <NEW_HASH>
Split status: N/A (0)
Terminal

Then we use the <HASH> to tag that slot as test, and reset:

mcumgr -c testDK image test <NEW_HASH>
mcumgr -c testDK reset

The image will be swapped into secondary slot. We can check this with:

mcumgr -c testDK image list

Which should return:

Images:
 image=0 slot=0
    version: 0.0.0
    bootable: true
    flags: active
    hash: <NEW_HASH>
 image=0 slot=1
    version: 0.0.0
    bootable: true
    flags: confirmed
    hash: <OLD_HASH>
Split status: N/A (0)
Terminal

And if we reset the board, again, we can in the same way see that the image swaps back to the old firmware. This is because we passed test not confirm to mcumgr

Note

To restore the default DK debugger (Interface MCU) behavior with a virtual mass storage disk enabled, use the following J-Link command: MSDEnable. This command can be executed via J-Link Commander (on Windows) or JLinkExe (on Linux).

nRF5340 update

The application core of the nRF5340 can be updated, as explained above.

When doing DFU from the application, no extra configurations are needed to update the network core. Another DFU package file must be used for the network core. Instead of app_update.bin, use net_core_app_update.bin.

However, for Serial Recovery, some extra configurations are needed to update the network core. The needed configurations are listed in our docs on Developing with nRF5340 DK: MCUboot’s serial recovery of the networking core image.

Register an account
Already have an account? Log in
(All fields are required unless specified optional)

  • 8 or more characters
  • Upper and lower case letters
  • At least one number or special character

Forgot your password?
Enter the email associated with your account, and we will send you a link to reset your password.