Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions boot/zephyr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,10 @@ if(CONFIG_MCUBOOT_SERIAL)
zephyr_sources(boot_serial_extension_zephyr_basic.c)
endif()
endif()

if(CONFIG_BOOT_SERIAL_CDC_ACM)
zephyr_sources(usbd_cdc_serial.c)
endif()
endif()

if(NOT CONFIG_BOOT_SIGNATURE_TYPE_NONE AND NOT CONFIG_BOOT_BUILTIN_KEY AND NOT
Expand Down
48 changes: 47 additions & 1 deletion boot/zephyr/Kconfig.serial_recovery
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ config BOOT_SERIAL_UART

config BOOT_SERIAL_CDC_ACM
bool "CDC ACM"
select USB_DEVICE_STACK
select USB_DEVICE_STACK_NEXT
select USBD_CDC_ACM_CLASS
help
This setting will choose CDC ACM for serial recovery unless chosen
"zephyr,uart-mcumgr" is present, in which case the chosen takes
Expand All @@ -46,6 +47,51 @@ config BOOT_SERIAL_CDC_ACM

endchoice

if BOOT_SERIAL_CDC_ACM

config BOOT_SERIAL_CDC_ACM_VID
hex "USB Vendor ID for CDC ACM serial recovery"
default 0x2fe3
help
USB Vendor ID presented during serial recovery mode.
You must use your own VID for samples and applications outside of Zephyr Project.

config BOOT_SERIAL_CDC_ACM_PID
hex "USB Product ID for CDC ACM serial recovery"
default 0x0004
help
USB Product ID presented during serial recovery mode.
You must use your own PID for samples and applications outside of Zephyr Project.

config BOOT_SERIAL_CDC_ACM_MANUFACTURER_STRING
string "USB manufacturer string for CDC ACM serial recovery"
default "MCUBoot"
help
USB manufacturer string descriptor for serial recovery mode.

config BOOT_SERIAL_CDC_ACM_PRODUCT_STRING
string "USB product string for CDC ACM serial recovery"
default "CDC ACM serial recovery"
help
USB product string descriptor for serial recovery mode.

config BOOT_SERIAL_CDC_ACM_SELF_POWERED
bool "USB self-powered attribute for CDC ACM serial recovery"
help
Set the Self-powered attribute in the USB configuration descriptor.
When enabled, the device reports that it does not draw power from
the USB bus. Only enable this if the device is powered by an
independent supply during serial recovery mode.

config BOOT_SERIAL_CDC_ACM_MAX_POWER
int "USB bMaxPower value for CDC ACM serial recovery"
default 125
range 0 250
help
bMaxPower value in the configuration in 2 mA units.

endif # BOOT_SERIAL_CDC_ACM

config MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD
bool "Allow to select image number for DFU"
depends on !SINGLE_APPLICATION_SLOT
Expand Down
10 changes: 5 additions & 5 deletions boot/zephyr/boards/nrf52840_big.overlay
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,17 @@

boot_partition: partition@0 {
label = "mcuboot";
reg = <0x000000000 0x00010000>;
reg = <0x000000000 0x00012000>;
};

slot0_partition: partition@10000 {
slot0_partition: partition@12000 {
label = "image-0";
reg = <0x000010000 0x000074000>;
reg = <0x000012000 0x000073000>;
};

slot1_partition: partition@75000 {
slot1_partition: partition@85000 {
label = "image-1";
reg = <0x00084000 0x000074000>;
reg = <0x00085000 0x000073000>;
};
};
};
Expand Down
5 changes: 0 additions & 5 deletions boot/zephyr/boards/nrf52840dongle_nrf52840.conf
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,4 @@ CONFIG_BOOT_SERIAL_CDC_ACM=y
# Required by USB
CONFIG_MULTITHREADING=y

# USB
CONFIG_USB_DEVICE_STACK=y
CONFIG_USB_DEVICE_REMOTE_WAKEUP=n
CONFIG_USB_DEVICE_PRODUCT="MCUBOOT"

CONFIG_NORDIC_QSPI_NOR=n
32 changes: 32 additions & 0 deletions boot/zephyr/boards/nrf52840dongle_nrf52840_big.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (c) 2026 Tolt Technologies
*
* SPDX-License-Identifier: Apache-2.0
*/

/delete-node/ &boot_partition;
/delete-node/ &slot0_partition;
/delete-node/ &slot1_partition;

&flash0 {
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;

boot_partition: partition@1000 {
label = "mcuboot";
reg = <0x00001000 0x00010000>;
};

slot0_partition: partition@11000 {
label = "image-0";
reg = <0x00011000 0x00065000>;
};

slot1_partition: partition@76000 {
label = "image-1";
reg = <0x00076000 0x00065000>;
};
};
};
27 changes: 27 additions & 0 deletions boot/zephyr/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,18 @@ const struct boot_uart_funcs boot_funcs = {
#include <zephyr/usb/class/usb_dfu.h>
#endif

#ifdef CONFIG_USB_DEVICE_STACK_NEXT
#include <zephyr/usb/usbd.h>
#endif /* CONFIG_USB_DEVICE_STACK_NEXT */

#ifdef CONFIG_BOOT_SERIAL_CDC_ACM
#include "usbd_cdc_serial.h"
#endif /* CONFIG_BOOT_SERIAL_CDC_ACM */

#if defined(CONFIG_BOOT_SERIAL_UART) && defined(CONFIG_LOG_BACKEND_UART)
#error "UART serial recovery and UART log backend cannot both be enabled"
#endif

#if CONFIG_MCUBOOT_CLEANUP_ARM_CORE
#include <arm_cleanup.h>
#endif
Expand Down Expand Up @@ -185,6 +197,21 @@ static void do_boot(struct boot_rsp *rsp)
/* Disable the USB to prevent it from firing interrupts */
usb_disable();
#endif
#ifdef CONFIG_USB_DEVICE_STACK_NEXT
{
int usbd_rc;

usbd_rc = usbd_disable(boot_usb_cdc_serial_get_context());

/* -EALREADY is expected on normal boot: USB was never enabled
* (lazy init -- only initialized when recovery is triggered).
* Any other error indicates a real problem.
*/
if (usbd_rc != 0 && usbd_rc != -EALREADY) {
BOOT_LOG_WRN("USB disable failed: %d", usbd_rc);
}
}
#endif
#if CONFIG_MCUBOOT_CLEANUP_ARM_CORE
cleanup_arm_interrupts(); /* Disable and acknowledge all interrupts */

Expand Down
2 changes: 1 addition & 1 deletion boot/zephyr/sample.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ tests:
platform_allow: nrf52840dongle/nrf52840
extra_args:
- EXTRA_CONF_FILE=./usb_cdc_acm_recovery.conf
- DTC_OVERLAY_FILE="./usb_cdc_acm.overlay;app.overlay"
- DTC_OVERLAY_FILE="./boards/nrf52840dongle_nrf52840_big.overlay;./usb_cdc_acm.overlay;app.overlay"
extra_configs:
- CONFIG_DEPRECATION_TEST=y
sample.bootloader.mcuboot.usb_cdc_acm_recovery_log:
Expand Down
57 changes: 42 additions & 15 deletions boot/zephyr/serial_adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
#include <string.h>
#include <zephyr/kernel.h>
#include "bootutil/bootutil_log.h"
#include <zephyr/usb/usb_device.h>
#include "mcuboot_config/mcuboot_config.h"
#include <zephyr/usb/usbd.h>

#if defined(CONFIG_BOOT_SERIAL_UART) && defined(CONFIG_UART_CONSOLE) && \
(!DT_HAS_CHOSEN(zephyr_uart_mcumgr) || \
Expand All @@ -40,6 +41,10 @@
(0 or above)
#endif

#if defined(CONFIG_BOOT_SERIAL_CDC_ACM)
#include "usbd_cdc_serial.h"
#endif

BOOT_LOG_MODULE_REGISTER(serial_adapter);

/** @brief Console input representation
Expand Down Expand Up @@ -213,24 +218,10 @@ boot_uart_fifo_init(void)
uart_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_console));
#endif

#elif defined(CONFIG_BOOT_SERIAL_CDC_ACM)
uart_dev = DEVICE_DT_GET_ONE(zephyr_cdc_acm_uart);
#else
#error No serial recovery device selected
#endif


if (!device_is_ready(uart_dev)) {
return (-1);
}

#if CONFIG_BOOT_SERIAL_CDC_ACM
int rc = usb_enable(NULL);
if (rc) {
return (-1);
}
#endif

uart_irq_callback_set(uart_dev, boot_uart_fifo_callback);

/* Drain the fifo */
Expand All @@ -246,5 +237,41 @@ boot_uart_fifo_init(void)

uart_irq_rx_enable(uart_dev);

#elif defined(CONFIG_BOOT_SERIAL_CDC_ACM)

int rc;

rc = boot_usb_cdc_serial_init();
if (rc) {
return (-1);
}

rc = usbd_enable(boot_usb_cdc_serial_get_context());
if (rc) {
return (-1);
}

/* Feed WDT while waiting for USB host to open the serial port.
* Without this, the hardware watchdog fires before the serial
* recovery loop (which feeds the WDT) is reached. */
while (k_sem_take(&boot_cdc_acm_ready, K_MSEC(5000)) != 0) {
#if CONFIG_BOOT_WATCHDOG_FEED
MCUBOOT_WATCHDOG_FEED();
#endif
}

uart_dev = DEVICE_DT_GET_ONE(zephyr_cdc_acm_uart);
if (!device_is_ready(uart_dev)) {
return (-1);
}

uart_irq_callback_set(uart_dev, boot_uart_fifo_callback);
cur = 0;
uart_irq_rx_enable(uart_dev);

#else
#error No serial recovery device selected
#endif

return 0;
}
4 changes: 4 additions & 0 deletions boot/zephyr/usb_cdc_acm_log_recovery.conf
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ CONFIG_UART_LINE_CTRL=y
# MCUBoot serial
CONFIG_MCUBOOT_SERIAL=y
CONFIG_BOOT_SERIAL_CDC_ACM=y
CONFIG_BOOT_SERIAL_CDC_ACM_PRODUCT_STRING="MCUBOOT"
CONFIG_USBD_MSG_DEFERRED_MODE=n
CONFIG_USBD_BOS_SUPPORT=n
CONFIG_USBD_VREQ_SUPPORT=n
5 changes: 5 additions & 0 deletions boot/zephyr/usb_cdc_acm_recovery.conf
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
CONFIG_MCUBOOT_SERIAL=y
CONFIG_BOOT_SERIAL_CDC_ACM=y
CONFIG_UART_CONSOLE=n

CONFIG_BOOT_SERIAL_CDC_ACM_PRODUCT_STRING="MCUBOOT"
CONFIG_USBD_MSG_DEFERRED_MODE=n
CONFIG_USBD_BOS_SUPPORT=n
CONFIG_USBD_VREQ_SUPPORT=n
Loading
Loading