Skip to content

Commit

Permalink
samples: usb: add sample for the new USB DFU implementation
Browse files Browse the repository at this point in the history
The sample defines an image that uses RAMdisk and also provides an
option to enable USB DFU flash backend for the "slot-1" flash partition.
Assuming the user runs this sample from the slot-0 partition, uploading
to flash should work fine for evaluation purposes.

If the sample is built with CONFIG_BOOTLOADER_MCUBOOT=y, the sample will
mark the image in slot 1 as pending after an image download.

Signed-off-by: Johann Fischer <[email protected]>
  • Loading branch information
jfischer-no committed Jan 24, 2025
1 parent 1bc28f6 commit c68a721
Show file tree
Hide file tree
Showing 7 changed files with 515 additions and 0 deletions.
9 changes: 9 additions & 0 deletions samples/subsys/usb/dfu-next/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(hid-keyboard)

include(${ZEPHYR_BASE}/samples/subsys/usb/common/common.cmake)
FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})
36 changes: 36 additions & 0 deletions samples/subsys/usb/dfu-next/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Copyright (c) 2023 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0

menu "USB DFU sample options"

config APP_USB_DFU_USE_FLASH_BACKEND
select FLASH
select FLASH_MAP
select STREAM_FLASH
select IMG_MANAGER
select IMG_ERASE_PROGRESSIVELY
bool "Option to clear the flash area before mounting"
help
Use this to force an existing file system to be created.

if APP_USB_DFU_USE_FLASH_BACKEND

config USBD_DFU_FLASH
default y

config USBD_DFU_FLASH_SLOT0
default n

config USBD_DFU_FLASH_SLOT1
default y

endif

endmenu

# Source common USB sample options used to initialize new experimental USB
# device stack. The scope of these options is limited to USB samples in project
# tree, you cannot use them in your own application.
source "samples/subsys/usb/common/Kconfig.sample_usbd"

source "Kconfig.zephyr"
137 changes: 137 additions & 0 deletions samples/subsys/usb/dfu-next/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
.. zephyr:code-sample:: dfu-next
:name: USB DFU
:relevant-api: usbd_api

Implement a basic USB DFU device

Overview
********

This sample application demonstrates the USB DFU implementation using the
new experimental USB device stack.

Requirements
************

This project requires an experimental USB device driver (UDC API) and uses the
:ref:`disk_access_api` and RAM-disk to download/upload the image.

Building and Running
********************

This sample can be built for multiple boards, in this example we will build it
for the reel board:

.. zephyr-app-commands::
:zephyr-app: samples/subsys/usb/dfu-next
:board: reel_board
:goals: build flash
:compact:

`dfu-util`_ tool can be used to download or upload the images. There are two
modes of operation in the USB DFU, runtime and DFU. The example starts in
runtime mode. To switch to DFU mode without uploading or downloading, the
following command can be used:

.. code-block:: console
dfu-util --detach
Use the following command to upload the ``ramdisk0`` image to the host:

.. code-block:: console
dfu-util --alt 0 --upload ramdisk0_backup.bin
Use the following command to download the ``ramdisk0`` image to the device:

.. code-block:: console
dfu-util --alt 0 --download ramdisk0_backup.bin
Building with flash backend enabled
***********************************

The USB DFU device support has a built-in flash backend. This backend uses
:ref:`flash_img_api` and :ref:`flash_map_api` to write or read flash image, the
implementation is similar to the one we had in the previous USB DFU device
example.

To use flash backend set the :kconfig:option:`CONFIG_APP_USB_DFU_USE_FLASH_BACKEND`.
An additional interface will be available in DFU mode to upload/download the
SLOT-1 image.

It is also possible to try the sample together with the MCUboot bootloader
library. The following example shows how to build MCUboot and this sample with
flash backend and MCUboot support enabled using the :ref:`sysbuild`:

.. zephyr-app-commands::
:tool: west
:zephyr-app: samples/subsys/usb/dfu-next
:board: reel_board
:goals: build flash
:west-args: --sysbuild
:gen-args: -DSB_CONFIG_BOOTLOADER_MCUBOOT=y -DCONFIG_APP_USB_DFU_USE_FLASH_BACKEND=y

Another application image is required to be used as a firmware update and
downloaded to SLOT-1. Build and sign a second application image e.g.
:zephyr:code-sample:`hello_world`, which will be used as an image for the
update. Do not forget to enable the required :kconfig:option:`CONFIG_BOOTLOADER_MCUBOOT`
option (as described in :ref:`mcuboot`). For example:

.. code-block:: console
west build -b reel_board zephyr/samples/hello_world -d build-hello_world -- \
-DCONFIG_BOOTLOADER_MCUBOOT=y \
'-DCONFIG_MCUBOOT_SIGNATURE_KEY_FILE="bootloader/mcuboot/root-rsa-2048.pem"'
Use the following command to download new image to the device:

.. code-block:: console
dfu-util --alt 1 --download build-hello_world/zephyr/zephyr.signed.bin
Reset the SoC. MCUboot boot will swap the images and boot the new application,
showing this output to the console:

.. code-block:: console
*** Booting MCUboot v2.1.0-rc1-134-gb9d69dd2a2d6 ***
*** Using Zephyr OS build v3.7.0-4345-ga5d0d8533a41 ***
I: Starting bootloader
I: Primary image: magic=good, swap_type=0x4, copy_done=0x1, image_ok=0x1
I: Secondary image: magic=good, swap_type=0x2, copy_done=0x3, image_ok=0x3
I: Boot source: none
I: Image index: 0, Swap type: test
I: Starting swap using move algorithm.
I: Bootloader chainload address offset: 0xc000
I: Image version: v0.0.0
I: Jumping to the first image slot
*** Booting Zephyr OS build v3.7.0-4345-ga5d0d8533a41 ***
Hello World! reel_board@1/nrf52840
Reset the SoC again and MCUboot should revert the images and boot
USB DFU sample, showing this output to the console:

.. code-block:: console
*** Booting MCUboot v2.1.0-rc1-134-gb9d69dd2a2d6 ***
*** Using Zephyr OS build v3.7.0-4345-ga5d0d8533a41 ***
I: Starting bootloader
I: Primary image: magic=good, swap_type=0x2, copy_done=0x1, 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: revert
I: Starting swap using move algorithm.
I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
I: Bootloader chainload address offset: 0xc000
I: Image version: v0.0.0
I: Jumping to the first image slot
*** Booting Zephyr OS build v3.7.0-4345-ga5d0d8533a41 ***
[00:00:00.000,335] <inf> main: USBD message: VBUS ready
[00:00:00.000,427] <inf> main: USB DFU sample is initialized
.. _dfu-util: https://dfu-util.sourceforge.net/
.. _Using MCUboot with Zephyr: https://docs.mcuboot.com/readme-zephyr
14 changes: 14 additions & 0 deletions samples/subsys/usb/dfu-next/app.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

/ {
ramdisk0 {
compatible = "zephyr,ram-disk";
disk-name = "image0";
sector-size = <512>;
sector-count = <32>;
};
};
10 changes: 10 additions & 0 deletions samples/subsys/usb/dfu-next/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
CONFIG_USB_DEVICE_STACK_NEXT=y
CONFIG_USBD_DFU=y

CONFIG_LOG=y
CONFIG_USBD_LOG_LEVEL_WRN=y
CONFIG_USBD_DFU_LOG_LEVEL_WRN=y
CONFIG_UDC_DRIVER_LOG_LEVEL_WRN=y
CONFIG_SAMPLE_USBD_PID=0x0005

CONFIG_DISK_ACCESS=y
18 changes: 18 additions & 0 deletions samples/subsys/usb/dfu-next/sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
sample:
name: USB DFU sample
common:
min_ram: 64
depends_on:
- usbd
integration_platforms:
- nrf52840dk/nrf52840
- frdm_k64f
- mimxrt1060_evk
tests:
sample.usbd.dfu:
tags: usb
sample.usbd.dfu-flash:
min_flash: 1024
tags: usb
extra_configs:
- CONFIG_APP_USB_DFU_USE_FLASH_BACKEND=y
Loading

0 comments on commit c68a721

Please sign in to comment.