In all previous exercises (exercise 1 to 3), we utilized DFU over UART using the onboard UART-to-USB converter available on the development kit. However, incorporating a UART-to-USB converter into your products is, in many cases, not practical, as it increases the bill of materials.
This exercise is only supported on nRF5340 DK, nRF52840 DK, nRF52833 DK, and nRF7002 DK since it requires an nRF SoC with a USB peripheral. For a list of which SoCs contain a USB peripheral, check the Nordic Product Guide – 2023, or Product Guide – 2024.
On the other hand, using DFU over USB is advantageous for several reasons. Firstly, many products will not include debugger UART-to-USB converters, making it challenging to perform firmware updates via UART. Some Nordic SoCs come with built-in USB peripheral, eliminating the need for additional hardware and simplifying the update process. This built-in USB support is a strong selling point for reducing the bill of materials for a product using wired DFU.
All the boards that support USB (by SoC and proper connector) have a corresponding definition in the board device tree file. As an example, we can look into the nrf5340dk board device tree.
zephyr_udc0: &usbd {
compatible = "nordic,nrf-usbd";
status = "okay";
};
DevicetreeIn addition, we can verify USB presence and it’s connections by looking into the board schematic file e.g: from the nrf5340dk hardware files.
nRF52 DK | nRF52840 DK | nRF52833 DK | nRF5340 DK | nRF54L15 DK | nRF91XX DKs | nRF7002 DK | |
USB | ❌ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ |
We will use the Zephyr CDC ACM drivers to communicate over USB. For more information on this, you can see USB device support.
We will first enable DFU over USB for serial recovery (In MCUboot) and then DFU from the application. We have covered the benefits of both options in Exercise 1. While both options could be active at the same time, as we show in this exercise, it is also possible to configure your project to support DFU in only one of the images. If you want to add USB to only MCUboot(aka: serial recovery), follow steps 1-4. If you want to add DFU over USB to only the application, follow step 5.
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 9 – Exercise 4.
USB configuration for Serial Recovery
1. Enable CDC ACM for Serial Recovery.
We need to configure both Kconfig and DTS for the MCUboot image to enable DFU over USB.
1.1 To enable CDC ACM for Serial Recovery, add CONFIG_BOOT_SERIAL_CDC_ACM
to sysbuild/mcuboot.conf
.
# STEP 1.1 - Configure serial recovery to use CDC_ACM, which by default uses the USB
CONFIG_BOOT_SERIAL_CDC_ACM=y
Kconfig2. Add a CDC ACM node to the devicetree.
We also need to add CDC_ACM to DTS.
2.1 Add the following snippet in sysbuild/mcuboot.overlay
(see USB device support).
/* STEP 2.1 - Configure CDC ACM */
&zephyr_udc0 {
cdc_acm_uart0: cdc_acm_uart0 {
compatible = "zephyr,cdc-acm-uart";
};
};
Devicetree2.2 Build the project.
We should now get the error (1). The size of the overflow will depend on which board is used because different boards can have different features enabled by default, which is inherited by MCUboot.
This error can come from any of the Sysbuild images, and it is not always obvious which image it comes from. We can see in (2) which image it is from, in this case, MCUboot. Therefore, we must either decrease features in MCUboot or increase the size of MCUboot. In this case: Since we added USB drivers to MCUboot, we need space.
3. Increasing the partition for the MCUboot bootloader.
3.1 Increase flash space for MCUboot child image, to fit USB drivers.
MCUboot partition size is 0xC000 by default. To increase this, set CONFIG_PM_PARTITION_SIZE_MCUBOOT
to 0x10000 in sysbuild/mcuboot.conf
. If you still get the above error, increase the size further. This is likely to be the case for the nRF5340 DK and the nRF7002 DK:
# STEP 3.1 - Increase flash space for MCUboot child image, to fit USB drivers
CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x10000
Kconfig4. Testing Serial Recovery over USB.
4.1 Build and flash the application to your board.
4.2 Connect to the nRF USB port.
In this step, we will assume that the hardware has no Debugger/Interface MCU (IMCU), and we will use the nRF USB port to transport the firmware images.
Disconnect your board from the regular Debugger USB port and connect to the nRF USB port. The nRF USB port is only available on the nRF5340 DK, nRF52840 DK, nRF52833 DK, and nRF7002 DK since it requires an nRF SoC with a USB peripheral.
4.3 Follow the steps in Exercise 1 – Steps 4.1 – 4.6, but connect via the nRF USB instead of the debugger USB.
USB configuration for DFU from the application
5. Change the application to use CDC ACM for DFU.
Next, we will change the application to use CDC ACM for DFU. The configuration we use here is inspired by the SMP Server sample.
5.1 In the file app.overlay
, we will first configure CDC ACM by adding the following:
/* STEP 5.1 - Configure CDC ACM */
&zephyr_udc0 {
cdc_acm_uart0: cdc_acm_uart0 {
compatible = "zephyr,cdc-acm-uart";
};
};
Devicetree5.2 Then we point the uart-mcumgr
driver to CDC ACM . by adding the line zephyr,uart-mcumgr = &cdc_acm_uart0;
as chosen.
/* STEP 5.2 - Choose CDC ACM for mcumgr */
/ {
chosen {
zephyr,uart-mcumgr = &cdc_acm_uart0;
};
};
Devicetree5.3 Next, we will have to add Kconfig options to prj.conf
:
# STEP 5.3 - Enable USB subsystem
CONFIG_USB_DEVICE_STACK=y
CONFIG_UART_LINE_CTRL=y
CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n
Kconfig5.4 Lastly, USB must be enabled in our source files (main.c
). First, include the header file for USB
/* STEP 5.4 - Include header for USB */
#include <zephyr/usb/usb_device.h>
C5.5 Enable USB in runtime
/* STEP 5.5 - Enable USB */
if (IS_ENABLED(CONFIG_USB_DEVICE_STACK)) {
ret = usb_enable(NULL);
if (ret) {
return 0;
}
}
C5.6 Build and flash the application to your board.
5.7 Connect your computer to the nRF USB port on the DK (this step was described in step 4.2).
5.8 Perform DFU for the DK in the way we learned in Exercise 1 – Steps 5.3 – 5.4, but connected via the nRF USB instead of the debugger USB.
DFU over USB is covered in Exercise 2 for v2.6.2 – v2.5.2