概述
USB DRD (Dual-Role Data) 是一种允许 USB 接口在主机与设备角色之间进行动态切换的功能。它打破了传统 USB 连接中角色固定的限制,使设备能够根据连接对象或应用需求灵活改变自身属性。
Ameba 能够软件控制切换角色,从而通过单一物理接口满足系统对扩展性与兼容性的双重需求。
DRD(设备)
DRD(主机)
应用场景
DRD 提升了设备灵活性,Ameba 可调整工作模式,通过单一物理接口适应适应多样化的的交互与扩展需求,例如:
智能行车记录仪/运动相机:在主机模式下,Ameba 主动将 GPS 模块轨迹写入外接 U 盘;当插入 PC 时切换为设备模式,模拟成大容量存储设备(MSC),供用户直接拷贝导出文件。
工业手持数据终端:在主机模式下,Ameba 连接扫码枪或红外传感器(HID/CDC)采集现场数据;当回到办公室连接 PC 时切换为设备模式,模拟成串口或 U 盘,将采集的日志与报表批量上传至管理系统。
车载 CarPlay 互联终端:Ameba 刚上电时处于设备模式,完成必要的初始验证流程;验证通过后切换为主机模式,主动连接车机设备,建立 NCM 和 iAP2 双协议通信以实现 CarPlay 全功能。
协议简介
在 USB 应用中,实现主机与设备角色的切换通常采用以下两种方法:
基于 USB OTG (On-The-Go) 协议的硬件切换
依赖物理线缆的 ID 引脚状态来判定角色。该机制包含以下具体协议:
SRP (Session Request Protocol): 允许从设备请求主机开启 VBUS 电源。
HNP (Host Negotiation Protocol): 允许连接双方通过协商临时交换 Host/Device 角色。
软件控制的 USB DRD 切换
不依赖物理连接状态,而是由软件直接修改控制器寄存器来进行角色变更。此方式虽不属于标准 USB 传输协议,但具有极高的实用价值。
DRD 软件切换对比 OTG 的核心优势
尽管硬件自动检测具备基础易用性,但在实现复杂、高可靠性的系统时, DRD 软件切换 展现出不可替代的优势:
摆脱硬件依赖与适配 Type-C
不依赖 ID 引脚,规避了因硬件设计缺陷或物理损坏导致的失效。
特别是在 Type-C 规范中,OTG 定义的 HNP 协议已被弃用,且无传统 ID 引脚,软件切换成为更符合现代接口规范的方案。
灵活的软件切换
支持在不更换物理线缆的情况下动态改变角色,可选择应用主动切换,或外部按键、事件或消息请求等多种方式触发切换。
极大提高了系统的容错率、可维护性以及自动化测试效率。
类驱动
USB DRD 软件控制角色切换本质上属于应用层的功能,主要涉及控制器工作模式的变更,本身并不需要特定的“DRD 类驱动”, 其实质是根据当前的 USB 角色,动态加载相应的标准类驱动。关于 DRD 不同角色下使用的类驱动,请参阅对应设备/主机方案的类驱动章节。
应用示例
应用设计
本节介绍 DRD 应用进行角色切换的开发设计流程,其中设备模式切换为主机模式过程可概括为(反之亦然):
加载设备驱动
主动切换或事件/消息等触发切换角色
卸载设备驱动
加载主机驱动
卸载主机驱动
在 MSC 设备和 MSC 主机 的 DRD 应用实例中,Ameba 先作为设备模式,20s 后通过软件强制切换为主机模式,下面介绍具体实现:
加载 MSC 设备驱动
定义配置结构体和回调函数,随后调用初始化接口,对底层存储初始化并加载 USB 设备核心驱动及 MSC 类驱动。
static usbd_config_t usbd_msc_cfg = {
.speed = CONFIG_USBD_MSC_SPEED,
.isr_priority = INT_PRI_MIDDLE,
};
static usbd_msc_cb_t usbd_msc_cb = {
.status_changed = usbd_msc_cb_status_changed /* USB status change callback. */
};
int ret = 0;
ret = usbd_msc_disk_init(); /* Initializes the underlying storage disk. */
if (ret != HAL_OK) {
return;
}
ret = usbd_init(&usbd_msc_cfg); /* Initialize USB device core driver with configuration. */
if (ret != HAL_OK) {
usbd_msc_disk_deinit();
return;
}
ret = usbd_msc_init(&usbd_msc_cb); /* Initializes the MSC device class. */
if (ret != HAL_OK) {
usbd_msc_disk_deinit();
usbd_deinit();
return;
}
卸载 MSC 设备驱动
按加载的反序释放资源。
/* De-initializes the underlying storage disk. */
usbd_msc_disk_deinit();
/* Deinitialize MSC device class driver. */
usbd_msc_deinit();
/* Deinitialize USB device core driver. */
usbd_deinit();
加载 MSC 主机驱动
定义配置结构体和回调函数,随后调用初始化接口,加载 USB 主机核心驱动及 MSC 类驱动。
static usbh_config_t usbh_cfg = {
.speed = USB_SPEED_HIGH,
.ext_intr_enable = USBH_SOF_INTR,
.isr_priority = INT_PRI_MIDDLE,
.main_task_priority = 3U,
.tick_source = USBH_SOF_TICK,
}
static usbh_msc_cb_t usbh_msc_usr_cb = {
.attach = usbh_msc_cb_attach, /* USB device attach callback */
.setup = usbh_msc_cb_setup, /* USB device setup done, indicate that device is ready for bulk transfer */
};
static usbh_user_cb_t usbh_usr_cb = {
.process = usbh_msc_cb_process
};
int ret = 0;
ret = usbh_init(&usbh_cfg, &usbh_usr_cb); /* Initialize USB host core driver with configuration and user callback. */
if (ret != HAL_OK) {
return;
}
ret = usbh_msc_init(&usbh_msc_usr_cb); /* Initializes the MSC host class with MSC class user callback. */
if (ret != HAL_OK) {
usbd_msc_disk_deinit();
return;
}
卸载 MSC 主机驱动
按加载的反序释放资源。
/* Deinitialize MSC host class driver. */
usbh_msc_deinit();
/* Deinitialize USB host core driver. */
usbh_deinit();
运行方式
本节介绍了一个具备运行时角色切换功能的 USB DRD 应用示例。该示例基于标准 MSC 类驱动,集成了大容量存储主机(MSC Host)与大容量存储设备(MSC Device)的双重功能。
在该示例中,Ameba 可在两种角色间切换:
MSC 设备模式:作为 MSC 设备连接主机(如 PC)后,可以读写其挂载的存储介质。
MSC 主机模式:作为 MSC 主机挂载并读写外部插入的 FAT32 文件系统的 MSC 设备(如 U 盘)。
该示例代码路径: {SDK}/component/example/usb/usb_drd,可为开发者设计自定义 USB DRD 产品提供完整的设计参考。
备注
本示例主要用于演示协议栈的双角色切换逻辑,不支持 SD 卡热插拔及 USB 接口热插拔。
配置与编译
Menuconfig 配置
在
amebaxxx_gcc_project目录下,输入./menuconfig.py,按下面步骤选择USB DRD和设备存储介质,保存退出。- Choose `CONFIG USB --->`: [*] Enable USB USB Mode (DRD) ---> *** USB Device Class *** [*] MSC Select storage media (SD Card (SD mode)) ---> *** USB Host Class *** [*] MSC编译与烧录
执行编译命令,并烧录生成的
Image文件至开发板:cd amebaxxx_gcc_project ./build.py -a usb_drd
结果验证
本小节以使用 SD 卡 作为存储介质为例进行演示。
启动设备
将 SD 卡插入开发板的 SD 卡槽并重启开发板,观察串口日志,应显示如下启动信息:
[DRD-I] USB DRD demo start [DRD-I] Init disk [DRD-I] Init disk [MSC-I] SD init [SDH-I] Card Detect [SDH-I] Voltage match [SDH-I] This is a SDHC/SDXC card... [SDH-I] Keep 3.3V... [SDH-I] Manufacturer ID:3 [SDH-I] OEM/Application ID:SD [SDH-I] Manufacturing date:2021/5 [SDH-I] RCA = AAAA [SDH-I] CSD Version:2.0 [SDH-I] User data area capacity: 14 GB [SDH-I] Max. read data block length: 512 Bytes [SDH-I] Max. write data block length: 512 Bytes [SDH-I] SD specification version: 3.0X [SDH-I] Data status after erase: 0 [SDH-I] SD card changes to the specified speed mode successfully [SDH-I] SD card is initialized [DRD-I] Init device driver [USBD-A] INIT [DRD-I] Init MSC device class [MSC-I] Init [DRD-I] MSC device session start
MSC 设备模式测试
用 USB 线缆将开发板连接到 PC(或其他支持 USB MSC 的主机设备)。
识别与挂载:PC 端文件管理器中应自动弹出一个新的可移动磁盘盘符。
读写测试:用户可以在 20 秒内双击打开该盘符,对其中的文件进行读写操作,验证数据传输是否正常。
角色切换:直到打印出以下日志,表示设备模式结束,准备切换至主机模式:
[DRD-I] Role switch [DRD-I] Deinit MSC device class [DRD-I] Deinit device driver [USBD-A] DEINIT [DRD-I] Deinit disk [MSC-I] SD deinit [DRD-I] Init host driver [DRD-I] Init MSC host driver [DRD-I] MSC host session start [DRD-I] Register USB disk [DRD-I] FatFS USB W/R performance test start...MSC 主机模式测试
将开发板的 USB 端口从 PC 断开,使用 USB 线缆将其连接到已格式化为 FATFS 的 U 盘,开发板将识别 MSC 设备并进行读写性能测试。
[USBH-A] Device attached,speed 0 [USBH-A] PID: 0x6545 [USBH-A] VID: 0x0930 [USBH-A] Address 1 assigned [USBH-A] MFG: TOSHIBA [USBH-A] PROD: TransMemory [USBH-A] SN: C03FD5F7715FE3417000DE76 [USBH-A] Enum done, total 1 cfg [USBH-A] Switch to itf: 0 [USBH-A] Class: 0x08 [USBH-A] SubClass: 0x06 [USBH-A] Protocol: 0x50 [DRD-I] Host attach [MSC-I] Max lun 1 [MSC-I] Lun 0 [DRD-I] Host setup [DRD-I] Open file: 0:/TEST0.DAT [DRD-I] W test: size 512, round 20... [DRD-I] W rate 204.0 KB/s for 20 round @ 49 ms [DRD-I] R test: size = 512 round = 20... [DRD-I] R rate 476.1 KB/s for 20 round @ 21 ms [DRD-I] W test: size 1024, round 20... [DRD-I] W rate 540.5 KB/s for 20 round @ 37 ms [DRD-I] R test: size = 1024 round = 20... [DRD-I] R rate 800.0 KB/s for 20 round @ 25 ms [DRD-I] W test: size 2048, round 20... [DRD-I] W rate 655.7 KB/s for 20 round @ 61 ms [DRD-I] R test: size = 2048 round = 20... [DRD-I] R rate 1212.1 KB/s for 20 round @ 33 ms [DRD-I] W test: size 4096, round 20... [DRD-I] W rate 1095.8 KB/s for 20 round @ 73 ms [DRD-I] R test: size = 4096 round = 20... [DRD-I] R rate 1600.0 KB/s for 20 round @ 50 ms [DRD-I] FatFS USB W/R performance test done [DRD-I] File close OK