Zephyr USB 设备栈提供了一个完整的 USB 设备端实现,支持多种 USB 类(HID、CDC、MSC、MIDI 等)。
当前 Zephyr 主线样例多数已经切到新的 USB device stack(CONFIG_USB_DEVICE_STACK_NEXT=y,运行时调用 usbd_enable());本文中涉及的 usb_enable() / usb_disable() 仍适合用来理解 legacy 栈模型,但属于旧接口。
┌─────────────────────────────────────────┐
│ 应用程序层 │
│ - USB HID 应用 / USB CDC 应用 │
├─────────────────────────────────────────┤
│ USB 类驱动 │
│ - HID / CDC / MSC / MIDI / Audio │
├─────────────────────────────────────────┤
│ USB 设备层 │
│ - 枚举处理 / 标准请求 / 端点管理 │
├─────────────────────────────────────────┤
│ USB 控制器驱动 │
│ - nRF52 / nRF53 / nRF54 USB 控制器 │
├─────────────────────────────────────────┤
│ 硬件层 │
│ - USB PHY / 端点硬件 │
└─────────────────────────────────────────┘
#include <zephyr/drivers/usb/udc.h>
/* 获取 USB 控制器设备 */
const struct device *udc_dev = DEVICE_DT_GET(DT_NODELABEL(usbd));
/* 初始化 USB 控制器 */
int ret = udc_init(udc_dev, NULL);
if (ret != 0) {
LOG_ERR("UDC init failed: %d", ret);
}
#include <zephyr/usb/usb_device.h> // legacy
#include <zephyr/usb/usbd.h> // current stack
/* 启用 USB 设备栈 */
int usb_enable(usb_dc_status_callback status_cb);
/* 禁用 USB 设备栈 */
int usb_disable(void);
/* 获取 USB 状态 */
enum usb_dc_status_code usb_get_status(void);
/* USB 状态变化回调 */
void usb_status_callback(enum usb_dc_status_code status, const uint8_t *param)
{
switch (status) {
case USB_DC_CONNECTED:
LOG_INF("USB connected");
break;
case USB_DC_CONFIGURED:
LOG_INF("USB configured - ready for communication");
break;
case USB_DC_DISCONNECTED:
LOG_INF("USB disconnected");
break;
case USB_DC_SUSPEND:
LOG_INF("USB suspended (low power mode)");
break;
case USB_DC_RESUME:
LOG_INF("USB resumed from suspend");
break;
case USB_DC_RESET:
LOG_INF("USB bus reset");
break;
case USB_DC_ERROR:
LOG_ERR("USB error occurred");
break;
}
}
主机 设备
│ │
├──── 总线复位 ────────>│
│ │
├──── 获取设备描述符 ──>│
│<──── 设备描述符 ─────┤
│ │
├──── 设置地址 ────────>│
│ │ (分配新地址)
│ │
├──── 获取配置描述符 ──>│
│<──── 配置描述符 ─────┤
│ │
├──── 设置配置 ────────>│
│ │ (激活配置)
│<──── ACK ────────────┤
│ │
[设备枚举完成,可以传输数据]
/* USB 标准请求 */
enum usb_request_type {
USB_REQ_GET_STATUS = 0,
USB_REQ_CLEAR_FEATURE = 1,
USB_REQ_SET_FEATURE = 3,
USB_REQ_SET_ADDRESS = 5,
USB_REQ_GET_DESCRIPTOR = 6,
USB_REQ_SET_DESCRIPTOR = 7,
USB_REQ_GET_CONFIGURATION = 8,
USB_REQ_SET_CONFIGURATION = 9,
USB_REQ_GET_INTERFACE = 10,
USB_REQ_SET_INTERFACE = 11,
USB_REQ_SYNCH_FRAME = 12,
};
/* 描述符类型 */
enum usb_descriptor_type {
USB_DESC_DEVICE = 1,
USB_DESC_CONFIGURATION = 2,
USB_DESC_STRING = 3,
USB_DESC_INTERFACE = 4,
USB_DESC_ENDPOINT = 5,
USB_DESC_DEVICE_QUALIFIER = 6,
USB_DESC_OTHER_SPEED = 7,
USB_DESC_INTERFACE_POWER = 8,
USB_DESC_OTG = 9,
};
| 类型 | 用途 | 特点 |
|---|---|---|
| 控制 (Control) | 枚举、配置 | 可靠、双向 |
| 中断 (Interrupt) | HID、小数据量 | 定期轮询、低延迟 |
| 批量 (Bulk) | 大容量存储 | 可靠、带宽保证 |
| 等时 (Isochronous) | 音频、视频 | 实时、无重传 |
/* 写入端点 (IN 传输到主机) */
int usb_write(uint8_t ep, const uint8_t *data, uint32_t data_len, uint32_t *bytes_ret);
/* 读取端点 (OUT 传输从主机) */
int usb_read(uint8_t ep, uint8_t *data, uint32_t max_data_len, uint32_t *ret_bytes);
/* 设置端点回调 */
void usb_set_endpoint_callback(uint8_t ep, usb_ep_callback cb);
/* 端点配置结构 */
struct usb_ep_cfg_data {
uint8_t ep_addr; /* 端点地址 */
uint16_t ep_mps; /* 最大包大小 */
usb_ep_callback ep_cb; /* 回调函数 */
};
/* 端点地址格式 */
#define USB_EP_DIR_MASK 0x80
#define USB_EP_DIR_IN 0x80
#define USB_EP_DIR_OUT 0x00
#define USB_EP_NUM_MASK 0x0F
/* 示例:端点地址 */
#define EP_IN_ADDR 0x81 /* 端点 1 IN */
#define EP_OUT_ADDR 0x01 /* 端点 1 OUT */
# 当前样例主线
CONFIG_USB_DEVICE_STACK_NEXT=y
# legacy 栈
# CONFIG_USB_DEVICE_STACK=y
# USB 设备信息
CONFIG_USB_DEVICE_VID=0x2FE3
CONFIG_USB_DEVICE_PID=0x0100
CONFIG_USB_DEVICE_MANUFACTURER="MyCompany"
CONFIG_USB_DEVICE_PRODUCT="MyDevice"
CONFIG_USB_DEVICE_SN="1234567890"
# USB 日志
CONFIG_USB_DRIVER_LOG_LEVEL_INF=y
CONFIG_USB_DEVICE_LOG_LEVEL_INF=y
# 支持多个配置
CONFIG_USB_DEVICE_CONFIGURATION_COUNT=2
# 支持远程唤醒
CONFIG_USB_DEVICE_REMOTE_WAKEUP=y
# 支持自供电
CONFIG_USB_DEVICE_SELF_POWERED=y
#include <zephyr/kernel.h>
#include <zephyr/usb/usb_device.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(usb_demo, LOG_LEVEL_INF);
/* USB 状态回调 */
static void usb_status_cb(enum usb_dc_status_code status, const uint8_t *param)
{
ARG_UNUSED(param);
switch (status) {
case USB_DC_CONFIGURED:
LOG_INF("USB configured");
break;
case USB_DC_DISCONNECTED:
LOG_INF("USB disconnected");
break;
default:
break;
}
}
void main(void)
{
int ret;
LOG_INF("USB Device Demo");
/* 启用 USB */
ret = usb_enable(usb_status_cb);
if (ret != 0) {
LOG_ERR("USB enable failed: %d", ret);
return;
}
LOG_INF("USB device ready");
while (1) {
k_sleep(K_SECONDS(1));
}
}
CONFIG_USB_DRIVER_LOG_LEVEL_DBG=y
CONFIG_USB_DEVICE_LOG_LEVEL_DBG=y
# 查看 USB 设备
lsusb
lsusb -v -d <VID>:<PID>
# 查看 USB 日志
dmesg | grep usb
# USB 抓包
sudo modprobe usbmon
sudo cat /sys/kernel/debug/usb/usbmon/0u
*学习笔记创建时间: 2026-03-19*