Skip to content

usb: device_next: save some flash and RAM #90791

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
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
33 changes: 28 additions & 5 deletions include/zephyr/usb/usbd.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,10 +269,14 @@ struct usbd_status {
/**
* @brief Callback type definition for USB device message delivery
*
* The implementation uses the system workqueue, and a callback provided and
* registered by the application. The application callback is called in the
* context of the system workqueue. Notification messages are stored in a queue
* and delivered to the callback in sequence.
* If the Kconfig option USBD_MSG_DEFERRED_MODE is enabled, then the callback
* is executed in the context of the system workqueue. Notification messages are
* stored in a queue and delivered to the callback in sequence.
*
* If the Kconfig option USBD_MSG_DEFERRED_MODE is disabled, the callback is
* executed in the context of the USB device stack thread. The user should make
* sure that the callback execution does not block or disrupt device stack
* handling.
*
* @param[in] ctx Pointer to USB device support context
* @param[in] msg Pointer to USB device message
Expand Down Expand Up @@ -493,6 +497,7 @@ static inline void *usbd_class_get_private(const struct usbd_class_data *const c
.iSerialNumber = 0, \
.bNumConfigurations = 0, \
}; \
IF_ENABLED(USBD_SUPPORTS_HIGH_SPEED, ( \
static struct usb_device_descriptor \
hs_desc_##device_name = { \
.bLength = sizeof(struct usb_device_descriptor), \
Expand All @@ -510,11 +515,14 @@ static inline void *usbd_class_get_private(const struct usbd_class_data *const c
.iSerialNumber = 0, \
.bNumConfigurations = 0, \
}; \
)) \
static STRUCT_SECTION_ITERABLE(usbd_context, device_name) = { \
.name = STRINGIFY(device_name), \
.dev = udc_dev, \
.fs_desc = &fs_desc_##device_name, \
IF_ENABLED(USBD_SUPPORTS_HIGH_SPEED, ( \
.hs_desc = &hs_desc_##device_name, \
)) \
}

/**
Expand Down Expand Up @@ -667,11 +675,15 @@ static inline void *usbd_class_get_private(const struct usbd_class_data *const c
* The application defines a BOS capability descriptor node for descriptors
* such as USB 2.0 Extension Descriptor.
*
* @note It requires Kconfig options USBD_BOS_SUPPORT to be enabled.
*
* @param name Descriptor node identifier
* @param len Device Capability descriptor length
* @param subset Pointer to a Device Capability descriptor
*/
#define USBD_DESC_BOS_DEFINE(name, len, subset) \
BUILD_ASSERT(IS_ENABLED(CONFIG_USBD_BOS_SUPPORT), \
"USB device BOS support is disabled"); \
static struct usbd_desc_node name = { \
.bos = { \
.utype = USBD_DUT_BOS_NONE, \
Expand All @@ -684,12 +696,16 @@ static inline void *usbd_class_get_private(const struct usbd_class_data *const c
/**
* @brief Define a vendor request with recipient device
*
* @note It requires Kconfig options USBD_VREQ_SUPPORT to be enabled.
*
* @param name Vendor request identifier
* @param vcode Vendor request code
* @param vto_host Vendor callback for to-host direction request
* @param vto_dev Vendor callback for to-device direction request
*/
#define USBD_VREQUEST_DEFINE(name, vcode, vto_host, vto_dev) \
BUILD_ASSERT(IS_ENABLED(CONFIG_USBD_VREQ_SUPPORT), \
"USB device vendor request support is disabled"); \
static struct usbd_vreq_node name = { \
.code = vcode, \
.to_host = vto_host, \
Expand All @@ -705,6 +721,9 @@ static inline void *usbd_class_get_private(const struct usbd_class_data *const c
* USBD_DESC_BOS_VREQ_DEFINE(bos_vreq_webusb, sizeof(bos_cap_webusb), &bos_cap_webusb,
* SAMPLE_WEBUSB_VENDOR_CODE, webusb_to_host_cb, NULL);
*
* @note It requires Kconfig options USBD_VREQ_SUPPORT and USBD_BOS_SUPPORT to
* be enabled.
*
* @param name Descriptor node identifier
* @param len Device Capability descriptor length
* @param subset Pointer to a Device Capability descriptor
Expand All @@ -713,6 +732,8 @@ static inline void *usbd_class_get_private(const struct usbd_class_data *const c
* @param vto_dev Vendor callback for to-device direction request
*/
#define USBD_DESC_BOS_VREQ_DEFINE(name, len, subset, vcode, vto_host, vto_dev) \
BUILD_ASSERT(IS_ENABLED(CONFIG_USBD_BOS_SUPPORT), \
"USB device BOS support is disabled"); \
USBD_VREQUEST_DEFINE(vreq_nd_##name, vcode, vto_host, vto_dev); \
static struct usbd_desc_node name = { \
.bos = { \
Expand Down Expand Up @@ -746,10 +767,12 @@ static inline void *usbd_class_get_private(const struct usbd_class_data *const c
usbd_class_fs, usbd_class_node, class_name##_fs) = { \
.c_data = &class_name, \
}; \
IF_ENABLED(USBD_SUPPORTS_HIGH_SPEED, ( \
static STRUCT_SECTION_ITERABLE_ALTERNATE( \
usbd_class_hs, usbd_class_node, class_name##_hs) = { \
.c_data = &class_name, \
}
} \
))

/** @brief Helper to declare request table of usbd_cctx_vendor_req
*
Expand Down
13 changes: 13 additions & 0 deletions samples/subsys/usb/cdc_acm/sample.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,19 @@ tests:
type: one_line
regex:
- "Wait for DTR"
sample.usb_device_next.cdc-acm-workqueue:
depends_on: usbd
tags: usb
extra_args:
- CONF_FILE="usbd_next_prj.conf"
- DCONFIG_USBD_CDC_ACM_WORKQUEUE=y
integration_platforms:
- frdm_k64f
harness: console
harness_config:
type: one_line
regex:
- "Wait for DTR"
sample.usb.cdc-acm.buildonly:
depends_on: usb_device
tags: usb
Expand Down
1 change: 1 addition & 0 deletions samples/subsys/usb/common/Kconfig.sample_usbd
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ config SAMPLE_USBD_MAX_POWER

config SAMPLE_USBD_20_EXTENSION_DESC
bool "Use default USB 2.0 Extension Descriptor"
depends on USBD_BOS_SUPPORT
help
Set bcdUSB value to 0201 and use default USB 2.0 Extension Descriptor.

Expand Down
18 changes: 10 additions & 8 deletions samples/subsys/usb/common/sample_usbd_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ USBD_CONFIGURATION_DEFINE(sample_hs_config,
CONFIG_SAMPLE_USBD_MAX_POWER, &hs_cfg_desc);
/* doc configuration instantiation end */

#if CONFIG_SAMPLE_USBD_20_EXTENSION_DESC
/*
* This does not yet provide valuable information, but rather serves as an
* example, and will be improved in the future.
Expand All @@ -72,6 +73,7 @@ static const struct usb_bos_capability_lpm bos_cap_lpm = {
};

USBD_DESC_BOS_DEFINE(sample_usbext, sizeof(bos_cap_lpm), &bos_cap_lpm);
#endif

static void sample_fix_code_triple(struct usbd_context *uds_ctx,
const enum usbd_speed speed)
Expand Down Expand Up @@ -175,16 +177,16 @@ struct usbd_context *sample_usbd_setup_device(usbd_msg_cb_t msg_cb)
/* doc device init-and-msg end */
}

if (IS_ENABLED(CONFIG_SAMPLE_USBD_20_EXTENSION_DESC)) {
(void)usbd_device_set_bcd_usb(&sample_usbd, USBD_SPEED_FS, 0x0201);
(void)usbd_device_set_bcd_usb(&sample_usbd, USBD_SPEED_HS, 0x0201);
#if CONFIG_SAMPLE_USBD_20_EXTENSION_DESC
(void)usbd_device_set_bcd_usb(&sample_usbd, USBD_SPEED_FS, 0x0201);
(void)usbd_device_set_bcd_usb(&sample_usbd, USBD_SPEED_HS, 0x0201);

err = usbd_add_descriptor(&sample_usbd, &sample_usbext);
if (err) {
LOG_ERR("Failed to add USB 2.0 Extension Descriptor");
return NULL;
}
err = usbd_add_descriptor(&sample_usbd, &sample_usbext);
if (err) {
LOG_ERR("Failed to add USB 2.0 Extension Descriptor");
return NULL;
}
#endif

return &sample_usbd;
}
Expand Down
23 changes: 22 additions & 1 deletion subsys/usb/device_next/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,20 @@ config USBD_MAX_SPEED
default 0 if USBD_MAX_SPEED_FULL
default 1 if USBD_MAX_SPEED_HIGH

config USBD_BOS_SUPPORT
bool "USB device BOS support"
default y
help
BOS support can be disabled if the application does not use a BOS
descriptor.

config USBD_VREQ_SUPPORT
bool "USB device vendor request support"
default y
help
Allow the application to register a handler for the vendor request
with the recipient device.

config USBD_SHELL
bool "USB device shell"
depends on SHELL
Expand Down Expand Up @@ -67,8 +81,15 @@ config USBD_MSG_SLAB_COUNT
help
Maximum number of USB device notification messages that can be queued.

config USBD_MSG_DEFERRED_MODE
bool "Execute message callback from system workqueue"
default y
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is a step in the right direction, however I would prefer this to be default n.

help
Execute message callback from system workqueue. If disabled, message
callback will be executed in the device stack context.

config USBD_MSG_WORK_DELAY
int "USB device notification messages work delay"
int "USB device notification messages work delay" if USBD_MSG_DEFERRED_MODE
range 1 100
default 1
help
Expand Down
15 changes: 15 additions & 0 deletions subsys/usb/device_next/class/Kconfig.cdc_acm
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,27 @@ config USBD_CDC_ACM_CLASS

if USBD_CDC_ACM_CLASS

config USBD_CDC_ACM_WORKQUEUE
bool "Use dedicated workqueue in CDC ACM"
help
Use the dedicated queue in CDC ACM implementation if the systemwork
queue cannot be used due to performance issues or other conflicts.

config USBD_CDC_ACM_STACK_SIZE
int "USB CDC ACM workqueue stack size"
depends on USBD_CDC_ACM_WORKQUEUE
default 1024
help
USB CDC ACM workqueue stack size.

config USBD_CDC_ACM_BUF_POOL
bool "Use dedicated buffer pool"
default y if !USBD_MAX_SPEED_FULL
help
Use a dedicated buffer pool whose size is based on the number of CDC
ACM instances and the size of the bulk endpoints. When disabled, the
implementation uses the UDC driver's pool.

module = USBD_CDC_ACM
module-str = usbd cdc_acm
default-count = 1
Expand Down
Loading