Zephyr RTOS的USB复合设备:CDC+MSC实现
概述
在嵌入式系统开发中,USB设备功能的灵活性至关重要。Zephyr RTOS提供了强大的USB设备栈,支持实现复合设备功能,即单个USB设备同时提供多种功能。本文将详细介绍如何在Zephyr RTOS中实现CDC(通信设备类)+MSC(大容量存储类)复合设备,使嵌入式设备同时具备虚拟串口和U盘功能。
硬件准备
实现USB复合设备需要以下硬件支持:
- 带有USB设备控制器的Zephyr支持开发板(如 reel_board)
- USB Type-C数据线
- 主机PC(用于测试和调试)
软件架构
Zephyr RTOS的USB复合设备实现基于以下核心组件:
1. USB设备控制器驱动
Zephyr的USB设备控制器驱动位于 drivers/usb/ 目录,提供底层USB硬件访问能力。
2. USB设备栈核心
核心实现位于 subsys/usb/ 目录,包括USB协议处理、配置管理和端点管理。
3. 功能类驱动
- CDC ACM类:subsys/usb/class/cdc_acm.c
- MSC类:subsys/usb/class/msc.c
4. 复合设备框架
复合设备框架允许将多个USB功能组合到单个设备中,相关实现位于 subsys/usb/composite.c。
实现步骤
1. 配置Kconfig选项
创建或修改应用目录下的 prj.conf
文件,添加以下配置:
# 启用USB设备支持
CONFIG_USB_DEVICE_STACK=y
# 启用CDC ACM功能
CONFIG_USB_CDC_ACM=y
CONFIG_USB_CDC_ACM_RINGBUF_SIZE=1024
# 启用MSC功能
CONFIG_USB_MSC=y
CONFIG_USB_MSC_STORAGE=y
# 启用复合设备支持
CONFIG_USB_COMPOSITE_DEVICE=y
# 配置USB描述符
CONFIG_USB_DEVICE_MANUFACTURER="Zephyr"
CONFIG_USB_DEVICE_PRODUCT="CDC+MSC Composite Device"
CONFIG_USB_DEVICE_SN="0001"
2. 设备树配置
创建或修改应用目录下的 boards/<board>.overlay
文件,添加USB节点配置:
&usb0 {
status = "okay";
compatible = "zephyr,usb-device";
};
/* MSC存储介质配置 (示例使用RAM盘) */
ramdisk: ramdisk {
compatible = "zephyr,ram-disk";
label = "RAMDISK";
size = <0x100000>; /* 1MB */
};
3. 应用代码实现
创建 src/main.c
文件,实现复合设备初始化:
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/usb/usb_device.h>
#include <zephyr/usb/class/cdc_acm.h>
#include <zephyr/usb/class/msc.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(usb_composite, LOG_LEVEL_INF);
/* CDC ACM设备实例 */
static const struct device *cdc_acm_dev;
/* MSC存储设备实例 */
static const struct device *msc_dev;
/* USB复合设备配置 */
static const struct usb_configuration composite_config = {
.label = "CDC+MSC Composite",
.configuration_number = 1,
.attributes = USB_CONFIG_ATTR_BUS_POWERED,
.max_power = 100, /* 100mA */
};
static void usb_status_cb(enum usb_dc_status_code status, const uint8_t *param)
{
LOG_INF("USB status: %s", usb_dc_status_str(status));
}
void main(void)
{
int ret;
LOG_INF("USB CDC+MSC Composite Device Example");
/* 初始化CDC ACM设备 */
cdc_acm_dev = DEVICE_DT_GET_ANY(zephyr_cdc_acm_uart);
if (!device_is_ready(cdc_acm_dev)) {
LOG_ERR("CDC ACM device not ready");
return;
}
/* 初始化MSC设备 */
msc_dev = DEVICE_DT_GET_ANY(zephyr_usb_msc);
if (!device_is_ready(msc_dev)) {
LOG_ERR("MSC device not ready");
return;
}
/* 初始化USB设备 */
ret = usb_set_config(&composite_config);
if (ret != 0) {
LOG_ERR("Failed to set USB configuration: %d", ret);
return;
}
/* 注册USB状态回调 */
ret = usb_set_status_callback(usb_status_cb);
if (ret != 0) {
LOG_ERR("Failed to set USB status callback: %d", ret);
return;
}
/* 启动USB设备 */
ret = usb_enable(NULL);
if (ret != 0) {
LOG_ERR("Failed to enable USB device: %d", ret);
return;
}
LOG_INF("USB composite device initialized successfully");
/* 主循环 */
while (1) {
k_sleep(K_SECONDS(1));
}
}
4. 添加CDC ACM回环功能
修改 src/main.c
,添加CDC ACM数据回环处理:
/* CDC ACM接收缓冲区 */
static uint8_t cdc_rx_buf[256];
/* CDC ACM接收回调 */
static void cdc_acm_receive_cb(const struct device *dev, void *user_data)
{
int len;
len = cdc_acm_read(dev, cdc_rx_buf, sizeof(cdc_rx_buf));
if (len > 0) {
/* 将接收到的数据回传 */
cdc_acm_write(dev, cdc_rx_buf, len);
}
}
/* 在main函数中注册CDC ACM回调 */
ret = cdc_acm_set_receive_callback(cdc_acm_dev, cdc_acm_receive_cb, NULL);
if (ret != 0) {
LOG_ERR("Failed to set CDC ACM receive callback: %d", ret);
return;
}
5. 配置MSC存储介质
在应用初始化代码中添加MSC存储介质配置:
/* MSC存储介质配置 */
static const struct msc_lun g_msc_lun = {
.media_type = MSC_MEDIA_TYPE_RAM,
.capacity = 0x2000, /* 扇区数 */
.block_size = 512, /* 扇区大小 */
.read = ramdisk_read,
.write = ramdisk_write,
};
/* 在main函数中注册MSC LUN */
ret = msc_register_storage(msc_dev, &g_msc_lun, 1);
if (ret != 0) {
LOG_ERR("Failed to register MSC storage: %d", ret);
return;
}
构建与测试
1. 构建应用
使用west命令构建应用:
west build -b reel_board samples/subsys/usb/composite
west flash
2. 测试CDC功能
- 将开发板通过USB连接到PC
- 观察系统日志(Linux下使用
dmesg
):usb 1-1: new full-speed USB device number X using xhci_hcd usb 1-1: New USB device found, idVendor=2fe3, idProduct=0100 usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 usb 1-1: Product: CDC+MSC Composite Device usb 1-1: Manufacturer: Zephyr usb 1-1: SerialNumber: 0001 cdc_acm 1-1:1.0: ttyACM0: USB ACM device usb-storage 1-1:1.2: USB Mass Storage device detected scsi host Y: usb-storage 1-1:1.2
- 使用串口工具连接到
/dev/ttyACM0
(Linux)或相应的COM端口(Windows) - 发送数据,验证回环功能
3. 测试MSC功能
- PC应自动识别USB存储设备
- 打开文件管理器,应显示一个新的可移动磁盘
- 尝试向磁盘复制文件,验证读写功能
故障排除
常见问题及解决方法
问题 | 解决方法 |
---|---|
USB设备未被识别 | 检查USB线连接,确认Kconfig配置中启用了正确的USB控制器 |
CDC串口无响应 | 检查CDC ACM回调注册,确认环形缓冲区大小配置 |
MSC存储无法挂载 | 检查存储介质配置,确认扇区大小和数量设置正确 |
设备枚举失败 | 检查USB描述符配置,确保复合设备配置正确 |
总结
通过Zephyr RTOS的USB复合设备框架,我们可以轻松实现CDC+MSC复合设备功能。这种方法不仅节省了硬件资源,还简化了嵌入式设备与主机的交互方式。开发者可以根据需求扩展该框架,添加更多USB功能类,如HID或音频类。
完整的示例代码可以参考Zephyr源码中的 samples/subsys/usb/composite/ 目录。更多USB设备开发细节请参考官方文档 doc/connectivity/usb.rst。
希望本文能帮助您快速掌握Zephyr RTOS的USB复合设备开发技巧。如有任何问题,欢迎在Zephyr社区提问交流。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考