透传设备方案

概述

CDC ACM 类为通信设备类(Communication Device Class​,CDC)的抽象控制模型(Abstract Control Model,ACM)子类,可用于模拟 COM 端口,实现数据透传。

SDK 提供了:

  • 标准的 CDC ACM 设备类驱动,特征如下:

    • 可配置批量 IN/OUT 的传输长度

    • 可配置中断 IN 端点是否使能,方便在不需要中断 IN 的应用中节省带宽

    • 端点配置如下:

      • 一个控制 IN/OUT 端点用于处理 USB 主机发送的控制请求

      • 一个中断 IN 端点用于向 USB 主机发送设备端的状态信息

      • 一个批量 IN 端点用于向 USB 主机发送数据

      • 一个批量 OUT 端点用于从 USB 主机接收数据

  • 基于 CDC ACM 标准设备类驱动的虚拟串口应用示例,特征如下:

    • 在主机端可被识别为标准串口设备,支持通用的串口工具,例如 PuTTY/TeraTerm

    • 执行数据回显操作,即通过批量 OUT 端点接收主机发送的批量 OUT 数据,并通过批量 IN 端点将数据发送回主机

    • 支持热插拔

类驱动

CDC ACM 设备类驱动

应用示例

示例路径: {SDK}/component/example/usb/usbd_cdc_acm

该示例定义了一个虚拟串口设备,USB 主机端可以用通用的串口工具与之通信,设备端会返回任何主机端下发的数据。

更多信息,请参考示例路径下的 README.md 文件。

该示例可作为基于 USB 批量传输的透传方案的设计参考。

HID 设备方案

概述

HID 设备类定义了标准化的人机接口设备(Human Interface Device),通过报表描述符定义的数据格式,使用控制或中断传输方式与 HID 主机进行通信。

USB 协议栈提供了:

  • HID 键盘和鼠标设备类驱动

    • HID 键盘设备类驱动的端点配置如下:

      • 一个控制 IN/OUT 端点用于处理 USB 主机发送的控制请求

      • 一个中断 IN 端点用于向 USB 主机发送按键信息

      • 一个中断 OUT 端点用于从 USB 主机接收控制指令

    • HID 鼠标设备类驱动的端点配置如下:

      • 一个控制端点用于处理 USB 主机发送的控制请求

      • 一个中断 IN 端点用于向 USB 主机发送按键信息

    • 支持描述符全定制

  • HID 键盘和鼠标应用示例,特征如下:

    • 支持基本的键盘和鼠标事件模拟

    • 支持 USB 热插拔

类驱动

HID 设备类驱动

应用示例

示例路径: {SDK}/component/example/usb/usbd_hid

该示例定义了一个 HID 键盘和鼠标设备,提供了与主机通信的简单测试示例。

更多信息,请参考示例路径下的 README.md 文件。

其中,HID 键盘示例可作为 USB HID 双向通信设备方案的设计参考,HID 鼠标示例可作为 USB HID 单向通信设备方案的设计参考。

存储设备方案

概述

MSC 设备类定义了标准化的大容量存储设备(Mass Storage Class),使用 SCSI(Small Computer System Interface)命令集与主机交互,支持对存储媒介的读写、擦除、查询等操作。

USB 协议栈提供了:

  • 标准的 MSC 设备类驱动,特征如下:

    • 基于 BOT(Bulk-Only Transport)传输协议

    • 支持 SD 卡和 RAM 两种存储媒介

    • 端点配置如下:

      • 一个控制 IN/OUT 端点用于处理 USB 主机发送的控制请求

      • 一个批量 IN 端点用于向 USB 主机发送数据

      • 一个批量 OUT 端点用于从 USB 主机接收数据

    • 支持描述符全定制

  • MSC 设备应用示例,特征如下:

    • 支持 USB 热插拔

    • 支持 SD 卡热插拔

备注

慎用 SD 卡热插拔功能,在传输过程中热插拔,有造成文件系统损坏、数据丢失的风险。

类驱动

MSC 设备类驱动

应用示例

示例路径: {SDK}/component/example/usb/usbd_msc

该示例定义了一个大容量存储设备,USB 主机端可通过 USB 访问设备存储媒介(例如 SD 卡)。

更多信息,请参考示例路径下的 README.md 文件。

该示例可作为 USB 存储设备方案的设计参考。

音频设备方案

概述

UAC(USB Audio Class)设备类定义了 USB 耳机、USB 麦克风、USB 声卡和其它音频设备的功能控制和接口标准。

UAC 各版本支持的音频参数如下:

../../../_images/usb_uac_overview.png

协议栈提供了 UAC 设备类驱动和对应的应用示例,特征如下:

  • 支持全速 UAC 1.0 扬声器功能,默认支持以下音频格式,可在应用层灵活配置:

采样率(kHz)

位宽

声道

2

4

6

8

44.1

16

Y

Y

Y

Y

24/32

Y

Y

48

16

Y

Y

Y

Y

24/32

Y

Y

96

16

Y

Y

24/32

Y

192

16

Y

24/32

  • 支持高速和全速 UAC 2.0 扬声器功能,默认支持以下音频格式,可在应用层灵活配置:

采样率(kHz)

位宽

声道

2

4

6

8

44.1

16

Y

Y

Y

Y

24/32

Y

Y

Y

Y

48

16

Y

Y

Y

Y

24/32

Y

Y

Y

Y

96

16

Y

Y

24/32

Y

Y

192

16

Y

24/32

Y

  • 端点配置如下:

    • 一个控制 IN/OUT 端点用于处理 USB 主机发送的控制请求

    • 一个等时 OUT 端点用于从 USB 主机接收音频数据

  • 支持音量、静音控制

  • 支持描述符全定制

  • 支持 USB 热插拔

备注

  • USB 设备核心驱动目前不支持 UAC2.0 高带宽端点,即每个帧/微帧最多只支持一笔等时传输,传输大小不超过等时 OUT 端点的最大包长

  • 整条音频通路支持的音频格式由 UAC 主机、UAC 设备硬件及软件框架、音频硬件及软件框架、基于 UAC 的音频应用共同决定

类驱动

UAC 设备类驱动

应用示例

示例路径: {SDK}/component/example/usb/usbd_uac

该示例定义了一个 UAC 扬声器设备,连接到 USB 主机后可被识别为扬声器。

更多信息,请参考示例路径下的 README.md 文件。

该示例可作为 USB 音频设备方案的设计参考。

FullMAC 设备方案

概述

基于 INIC(Internet Network Interface Controller),可实现基于 USB 的 FullMAC 解决方案,作为网卡通过 USB 与主机连接,为主机提供网络接入能力。

关于 FullMAC,参考 支持的芯片

USB 协议栈提供了:

  • INIC 设备类驱动,特征如下:

    • 支持 WiFi 单功能模式

    • 端点配置如下:

      • 一个控制 IN/OUT 端点用于处理 USB 主机发送的控制请求

      • 一个批量 IN 端点用于向 USB 主机发送数据

      • 两个批量 OUT 端点用于从 USB 主机接收数据

    • 支持描述符全定制

  • 基于 INIC 设备类驱动的 FullMAC 应用示例,特征如下:

    • 支持定制的 Linux 主机 FullMAC 驱动(联系 Realtek FAE)

    • 支持 USB 热插拔

类驱动

INIC 设备类驱动

应用示例

示例路径: {SDK}/component/example/usb/usbd_inic

该示例定义了一个 INIC 设备,主机端加载对应的专用设备驱动后可与之通信。

更多信息,请参考示例路径下的 README.md 文件。

该示例可作为 USB FullMAC 解决方案的设计参考。

复合功能设备方案

概述

USB 复合功能(Composite)设备是一种通过单一物理 USB 接口实现多种独立功能的 USB 设备,它通过将多个独立的 USB 功能单元以接口的形式组合在一起,使 USB 主机将其识别为多个虚拟设备的集合,从而解决了单一物理接口的扩展性问题。

协议栈提供了复合功能设备类驱动及对应的应用示例,特征如下:

  • 支持以下功能组合

    • CDC ACM + HID

    • CDC ACM + UAC

    • HID + UAC

  • 支持描述符全定制

  • 支持 USB 热插拔

类驱动

复合功能设备类驱动

应用示例

SDK 提供以下 USB Composite 示例:

路径

描述

{SDK}/component/example/usb/usbd_composite_cdc_acm_hid/

CDC ACM虚拟串口和HID鼠标应用示例

{SDK}/component/example/usb/usbd_composite_cdc_acm_uac/

CDC ACM虚拟串口和UAC扬声器应用示例

{SDK}/component/example/usb/usbd_composite_uac_hid/

UAC扬声器和自定义HID应用示例

更多信息,请参考对应示例路径下的 README.md 文件。

上述示例可作为 USB Composite 设备方案的设计参考。

自定义设备方案

概述

Vendor 类可作为开发者自定义 USB 设备的设计参考。

SDK 提供了:

  • Vendor 设备类驱动,特征如下:

    • 支持描述符全定制

    • 端点配置如下:

      • 一个控制 IN/OUT 端点用于处理 USB 主机发送的控制请求

      • 一对批量 IN/OUT 端点用于批量传输测试

      • 一对中断 IN/OUT 端点用于中断传输测试

      • 一对等时 IN/OUT 端点用于等时传输测试

  • 基于 Vendor 设备类驱动的应用示例,特征如下:

    • 与 Vendor 主机应用示例适配,具体参考 自定义主机方案

    • 执行批量/中断/等时传输的数据回显操作

    • 支持热插拔

类驱动

Vendor 设备类驱动

应用示例

示例路径: {SDK}/component/example/usb/usbd_vendor

该示例定义了一个自定义设备,支持批量/中断/等时传输的数据回显。

更多信息,请参考示例路径下的 README.md 文件。

该示例可作为 USB 厂商自定义方案设备端的设计参考。

设备描述符定制

描述符概述

USB 设备通过描述符定义设备功能,USB 描述符的拓扑结构示例如下图所示:

../../../_images/usb_device_descriptors_cn.svg

其中:

  • 一个 USB 设备只有一个设备描述符(Device Descriptor)

  • 一个 USB 设备可以有多个(由设备描述符的 bNumConfigurations 指定)配置描述符(Configuration Descriptor),但同时只允许一个配置描述符生效

  • 一个配置描述符下可以有多个(由配置描述符的 bNumInterfaces 指定)接口描述符(Interface Descriptor),且多个接口描述符可以同时生效

  • 一个接口描述符下可以有多个(由接口描述符的 bNumEndPoints 指定)端点描述符(Endpoint Descriptor),且多个端点描述符可以同时生效

另外,还有其它一些常用的描述符:

  • 设备描述符、配置描述符和接口描述符都有一些相关的功能描述,这些描述定义为字符描述符(String Descriptor)

  • 对于需要同时支持高速和全速模式的设备,还需要同时定义设备限定描述符(Device Qualifier Descriptor)和其它速率配置描述符(Other Speed Configuration Descriptor)

  • 对于复合设备,还需要在多个类接口描述符之前,增加一个接口关联描述符(Interface Association Descriptor,IAD)

  • 某些 USB 设备类需要定义与设备类相关的特定描述符,比如 HID 设备需要定义报表描述符(Report Descriptor)

备注

具体的描述符定义,请参考 USB 规范。

描述符数据结构

一般情况下,USB 主机会按如下顺序获取 USB 设备的描述符信息:

  • 获取设备描述符,USB 设备需要返回设备描述符信息

  • 获取配置描述符,USB 设备需要返回描述符拓扑结构中当前有效的配置描述符及其以下节点(包含接口描述符和端点描述符)的全部描述符信息

  • 获取配置描述符对应的字符串描述符,USB 设备需要根据主机控制请求中的字符串类型信息,返回当前有效配置描述符下对应的字符串描述符信息,包含语言 ID、串号、厂商、产品等字符串信息

另外,USB 主机可能还会尝试获取 USB 设备的以下描述符信息:

  • 获取设备限定描述符,如果 USB 设备有支持,需要返回设备限定描述符信息

  • 获取其它速率配置描述符,如果 USB 设备有支持,需要返回描述符拓扑结构中当前有效的配置描述符对应的其它速率配置描述符及其节点(包含接口描述符和端点描述符)的全部描述符信息

  • 获取其它速率配置描述符对应的字符串描述符,USB 设备需要根据主机控制请求中的字符串类型信息,返回当前有效配置描述符对应的其它速率配置描述符下对应的字符串描述符信息,包含语言 ID、串号、厂商、产品等字符串信息

  • 获取设备类相关的描述符,USB 设备需要根据设备类规范返回相关的描述符信息

  • 获取 USB 主机相关的描述符,比如 Windows 主机会尝试获取索引值为 238(对应 16 进制数字 0xEE)的 Microsoft OS 字符串描述符(Microsoft OS String Descriptor)

备注

如果 USB 设备不支持某些描述符,在收到 USB 主机端相关请求时,需要返回 STALL 状态,复合规范的 STALL 并不会影响 USB 主机与设备间的通信,也不会影响 USB 设备的功能。

鉴于上述 USB 主机获取 USB 设备描述符的行为,建议 USB 设备定义以下几个独立数组用于存储 USB 主机需要获取的描述符信息:

  • 设备描述符,仅包含设备描述符信息

  • 配置描述符,每个配置描述符分别定义,包含其自身及其以下节点(包含接口描述符和端点描述符)的全部描述符信息

  • 字符串描述符,包含语言 ID 在内的每个字符串描述符分别定义

  • 设备限定描述符,仅包含设备限定描述符信息

  • 其它速率配置描述符,每个其它速率配置描述符分别定义,包含其自身及其以下节点(包含接口描述符和端点描述符)的全部描述符信息;为节省存储资源,也可与配置描述符共用一个数组,运行时动态替换描述符类型数据

  • 设备类相关的描述符,按设备类规范定义

  • USB 主机相关的描述符,按 USB 主机相关规范和应用需求定义

描述符定制项

USB 设备协议栈中定义的所有设备类,其全部描述符信息均开源并允许开发者根据设计需求定制。 但为兼容性,对于基于 USB 规范的标准类设备,一般仅建议对以下描述符信息进行定制:

VID 与 PID

开发者可以直接使用 USB 协议栈默认使用的 Realtek VID 和 PID,如需自定义,需要注册成为 USB-IF 成员(参考 https://www.usb.org/members),然后按照 USB-IF 的流程申请 VID 和 PID。 开发者如果需要使用 Realtek VID,并自定义 PID,请与 Realtek FAE 联系。

备注

使用 Realtek VID 和 PID, 并不意味着产品符合 USB 规范,仍需要进行 USB 认证。

字符串描述符

设备描述符、配置描述符和接口描述符都有字符串描述符索引字段,可定义非 0 的索引值并定义对应的字符串描述符:

  • 设备描述符

    • iManufacturer:厂商字符串

    • iProduct:产品字符串

    • iSerialNumber:串号字符串

  • 配置描述符

    • iConfiguration:配置字符串

  • 接口描述符

    • iInterface:配置字符串

备注

  • USB 规范要求字符串描述符使用 UNICODE 编码,设备核心驱动提供了 usbd_get_str_desc 函数用于将 ASCII 编码的字符串转为 UNICODE 编码的字符串描述符,方便开发者用 ASCII 字符串来维护字符串信息。

  • 协议栈目前仅提供了英文字符串描述符示例,如需支持其它语言类型,请参考 USB 规范定义所需的语言 ID 描述符及对应的字符串描述符

端点描述符

对于一般应用,端点描述符中的以下字段支持自定义:

  • bEndpointAddress:端点地址

  • wMaxPacketSize:最大包长,一般建议按 USB 规范定义的最大值(不高于 SoC 硬件支持的最大值)来设定,除非有特别需求,不建议随意修改

  • bInterval:传输间隔

备注

协议栈保证默认提供的端点配置对所有 SoC 可用,如需调整,请参考 硬件配置,务必熟知相关 USB 规范和 SoC 硬件限制后再做谨慎调整,否则可能导致兼容性问题甚至枚举失败。

设备连接状态检测

对于自供电 USB 设备,当 USB 连接状态改变时,设备类驱动及应用层需要及时获悉相关事件并做对应处理,从而达成支持热插拔、降低功耗等目的。

USB 设备核心驱动提供了如下 API 用于设备类驱动及应用层检测 USB 连接状态:

上述 API 需要在 USB 上电之后,访问 USB 相关寄存器才能获得有效数据,因此需要在 USB 核心驱动初始化之后才能调用。 如果要在 USB 未上电时就能获取 USB 状态信息,需要借助外部电路的支持,例如通过 GPIO 中断来检测 VBUS 的上电掉电事件,具体请参考硬件设计手册(Hardware Design Guide)中的 USB 插入检测电路参考设计。

借助上述软硬件检测方案,可以分辨如下 USB 设备连接状态改变事件:

事件

usbd_get_status

status_changed

VBUS GPIO中断

VBUS状态

设备复位(保持与USB主机连接)

USBD_ATTACH_STATUS_ATTACHED

USBD_ATTACH_STATUS_INIT -> USBD_ATTACH_STATUS_ATTACHED

N/A

ON

设备复位(保持USB连接断开)

USBD_ATTACH_STATUS_INIT

N/A

N/A

OFF

设备复位(保持与USB充电器连接)

USBD_ATTACH_STATUS_INIT

N/A

N/A

ON

连接到USB主机

USBD_ATTACH_STATUS_ATTACHED

USBD_ATTACH_STATUS_DETACHED -> USBD_ATTACH_STATUS_ATTACHED

Y (上升沿)

OFF -> ON

从USB主机断开

USBD_ATTACH_STATUS_DETACHED

USBD_ATTACH_STATUS_ATTACHED -> USBD_ATTACH_STATUS_DETACHED

Y (下降沿)

ON -> OFF

连接到USB充电器

USBD_ATTACH_STATUS_INIT

or

USBD_ATTACH_STATUS_DETACHED

N/A

Y (上升沿)

OFF -> ON

从USB充电器断开

USBD_ATTACH_STATUS_INIT

or

USBD_ATTACH_STATUS_DETACHED

N/A

Y (下降沿)

ON -> OFF

USB连接挂起(suspend)

USBD_ATTACH_STATUS_DETACHED

USBD_ATTACH_STATUS_ATTACHED -> USBD_ATTACH_STATUS_DETACHED

与主机设置相关

与主机设置相关

USB连接恢复(resume)

USBD_ATTACH_STATUS_ATTACHED

USBD_ATTACH_STATUS_DETACHED -> USBD_ATTACH_STATUS_ATTACHED

与主机设置相关

与主机设置相关

两个典型的应用场景:

基于软件的解决方案

如果对功耗要求不严苛,允许 USB 电源常开,可通过 status_changed,只借助软件的方式获取设备连接状态改变事件,一般用法如下:

  • 检测到与 USB 主机断开连接时,终止通信,注销并重新注册 USB 设备,等待下次与 USB 主机连接

  • 检测到与 USB 主机连接时,恢复通信

具体处理流程参考下图:

../../../_images/usb_status_detection_sw_cn.svg

基于硬件辅助的解决方案

如果对功耗要求严苛,希望在 USB 设备与主机未连接时能够关闭 USB 相关电源,可通过 GPIO 中断来检测 VBUS 的上电掉电事件,一般用法如下:

  • 检测到与 USB 主机断开连接或者连接到 USB 充电器时,注销 USB 设备,以达省电目的

  • 检测到与 USB 主机连接时,注册 USB 设备,使能 USB 通信

具体处理流程参考下图:

../../../_images/usb_status_detection_hw_cn.svg