USB_基础概念

- USB靠 D+、D- 差分信号进行数据传输,所以在硬件设计的时候D+,D-需要遵循差分走线的原则,
- USB底层编码方式为反向不归零,为半双工,通信总线上在同一时刻只有一个方向数据传输
通信过程

域
- 域是最底层的信息单元,多个域组成一个包,类似组成完整句子的单词
- 同步域(SYNC):每个包的开头,用于同步时钟
- 包标识域(PID):标明包的类型(是令牌包、数据包还是握手包)
- 地址域(ADDR):USB设备的地址(7位)
- 端点域(ENDP):设备内的端点号(4位)
- 数据域(DATA):要传输的实际数据,长度0~1024字节。
- 循环冗余校验域(CRC):用于检错。
包
- 包是由多个域组成的完整信息单元。USB总线上传输的就是一个个包,包在信号层传输
- 令牌包(Token Packet):主机发出,告诉设备“我要做什么”。例如:“我要从你这里读数据(IN令牌)”或“我要给你发数据(OUT令牌)”
- 数据包(Data Packet):传输实际数据,可以是 DATA0、DATA1(用于同步)。
- 握手包(Handshake Packet):接收方回应“收到了(ACK)”、“正忙(NAK)”、“出错(STALL)”。
事务
- 事务是USB通讯的基本操作单元,通常包含2个或3个包
- IN事务(主机从设备读数据):主机发【IN令牌包】→ 设备回【数据包】→ 主机回【握手包(ACK/NAK/STALL)】
- OUT事务(主机向设备写数据):主机发【OUT令牌包】→ 主机发【数据包】→ 设备回【握手包】
- SETUP事务(控制传输的建立阶段):主机发【SETUP令牌包】→ 主机发【数据包】(8字节请求)→ 设备回【握手包】
传输
- 传输是由一个或多个事务组成的高层逻辑过程,完成一个完整的功能(如读取一个文件、发送一个鼠标移动数据)
| 传输类型 | 特点 | 用途 |
|---|---|---|
| 控制传输 | 主机获取设备配置和状态,有固定流程:设置阶段(SETUP事务)→ 数据阶段(IN/OUT事务)→ 状态阶段(IN/OUT事务) | 如插入U盘后主机获取设备描述符 |
| 批量传输 | 当一帧内的总线时间有空余时USB总线就会将时间分配给批量传输设备,有数据校验和重传机制 | 打印机、扫描仪、硬盘 |
| 中断传输 | 传输少量数据,有数据校验和重传,固定间隔 | 键鼠 |
| 同步传输 | 实时数据传输,有固定时间延迟,低速设备不支持 | 音频、视频 |
帧:一个固定的时间长度,低速/全速 1ms,高速125us, USB总线在数据传输时是按帧占用总线时间的,帧作用是同步等时传输、设置中断轮询周期、提供时间基准,主机会在每一帧内根据带宽预算(全速最多约 10 个最大包)合理安排事务,每个帧以 SOF 包 开始,SOF 包含帧号, *
- 示例:主机读取U盘的第一个扇区传输过程:
- 主机发出 CBW 命令(通过OUT事务发送SCSI读命令)
- 主机发出 IN事务 读取数据:
- 事务1:【IN令牌包】→ 设备回【数据包(64字节)】→ 主机回【ACK】
- 事务2:【IN令牌包】→ 设备回【数据包(64字节)】→ 主机回【ACK】
- 直到读完512字节
- 主机发出 IN事务 读取 CSW 状态包(确认命令完成)
USB描述符
- USB 描述符是遵循 USB 规范定义的一种数据结构,用于向USB主机(Host)报告设备的属性、能力、配置和通信方式。每个描述符以固定格式的字节数组存储于设备固件中,作用就像是设备的“身份证”和“说明书”。
- 在USB设备插入主机后的枚举阶段,主机主动请求读取描述符数据
-USB为主从通信架构,所有通信都是主机主动发起,从机被动相应
以CH585 EVT 例程中的HID_CompliantDev为例
设备描述符
// 设备描述符
const uint8_t MyDevDescr[] = {0x12,0x01,0x10,0x01,0x00,0x00,0x00,DevEP0SIZE,0x3d,0x41,0x07,0x21,0x00,0x00,0x00,0x00,0x00,0x01};
- USB标准设备描述符(Device Descriptor)长度为 18 字节
| 偏移量 | 值 | 字段名 | 含义 |
|---|---|---|---|
| 0 | 0x12 | bLength | 设备描述符长度,固定为18字节(0x12) |
| 1 | 0x01 | bDescriptorType | 描述符类型,0x01表示这是一个设备描述符 |
| 2-3 | 0x0110 | bcdUSB | 小端,设备遵循的 USB 规范版本号。0x0110 表示 USB 1.10(全速 12Mbps)CH585 实际支持USB 2.0高速,此处可以改为0x0200声明高速能力 |
| 4 | 0x00 | bDeviceClass | 设备类代码。0x00 表示 类由接口描述符指定 |
| 5 | 0x00 | bDeviceSubClass | 设备子类代码,通常与 bDeviceClass 配合,此处为 0。 |
| 6 | 0x00 | bDeviceProtocol | 设备协议代码,通常与 bDeviceClass 配合,此处为 0。 |
| 7 | 0x40 | bMaxPacketSize0 | 端点 0(控制端点)的最大数据包大小。常用值为 8、16、32、64。CH585 的 USB 控制器支持最大 64 字节。决定主机发包大小 |
| 8-9 | 0x413d | idVendor | 小端,供应商 ID(VID),由 USB-IF 分配,(如沁恒的 VID 是 0x4348)。 |
| 10-11 | 0x2107 | idProduct | 小端,产品 ID(PID),由厂商自行定义,用于区分不同产品。 |
| 12-13 | 0x0000 | bcdDevice | 设备发布版本号,以 BCD 码表示 |
| 14 | 0x00 | iManufacturer | 制造商字符串描述符的索引。0x00 表示 没有制造商字符串。 |
| 15 | 0x00 | iProduct | 产品字符串描述符的索引。0x00 表示 没有产品字符串。 |
| 16 | 0x00 | iSerialNumber | 序列号字符串描述符的索引。0x00 表示 没有序列号。 |
| 17 | 0x01 | bNumConfigurations | 该设备支持的配置描述符数量 |

配置描述符
// 配置描述符
const uint8_t MyCfgDescr[] = {
0x09,0x02,0x29,0x00,0x01,0x01,0x04,0xA0,0x23, //配置描述符
0x09,0x04,0x00,0x00,0x02,0x03,0x00,0x00,0x05, //接口描述符
0x09,0x21,0x00,0x01,0x00,0x01,0x22,0x22,0x00, //HID类描述符
0x07,0x05,0x81,0x03,DevEP1SIZE,0x00,0x01, //端点描述符
0x07,0x05,0x01,0x03,DevEP1SIZE,0x00,0x01 //端点描述符
};
- 配置描述符
| 偏移量 | 值 | 字段名 | 含义 |
|---|---|---|---|
| 0 | 0x09 | bLength | 配置描述符长度 |
| 1 | 0x02 | bDescriptorType | 描述符类型 |
| 2-3 | 0x0029 | wTotalLength | 整个配置描述符集合的总长度 |
| 4 | 0x01 | bNumInterfaces | 该配置下包含 1 个接口 |
| 5 | 0x01 | bConfigurationValue | 用该值作为 Set Configuration 命令的参数来激活此配置 |
| 6 | 0x04 | iConfiguration | 配置字符串描述符的索引 |
| 7 | 0xA0 | bmAttributes | D7: 保留(必须为 1)D6: 自供电(0 → 总线供电)D5: 远程唤醒(1 → 支持远程唤醒)D4~0: 保留(0) |
| 8 | 0x23 | bMaxPower | 设备在总线供电时需要的最大电流,单位为 2 mA, 0x23=35, Imax = 70mA |
接口描述符
| 偏移量 | 值 | 字段名 | 含义 |
|---|---|---|---|
| 0 | 0x09 | bLength | 固定 9字节,长度 |
| 1 | 0x04 | bDescriptorType | 类型,为接口描述符 |
| 2 | 0x00 | bInterfaceNumber | 该接口编号为 0 |
| 3 | 0x00 | bAlternateSetting | 备用设置编号(通常为 0) |
| 4 | 0x02 | bNumEndpoints | 该接口使用了 2 个端点(不包括端点 0) |
| 5 | 0x03 | bInterfaceClass | 类代码为 HID |
| 6 | 0x00 | bInterfaceSubClass | HID 子类 0:普通 HID 设备(报表描述符完全自定义) 1: 兼容 BIOS 的键盘/鼠标 |
| 7 | 0x00 | bInterfaceProtocol | 无协议,0 :无引导协议(普通 HID,需要自定义报告) 1:键盘(Boot Keyboard)—— BIOS 能用 2:鼠标(Boot Mouse)—— BIOS 能用 |
| 8 | 0x05 | iInterface | 接口字符串描述符索引 |
- HID类描述符
| 偏移量 | 值 | 字段名 | 含义 |
|---|---|---|---|
| 0 | 0x09 | bLength | 描述符长度 |
| 1 | 0x21 | bDescriptorType | 类型 |
| 2-3 | 0x0100 | bcdHID | HID 规范版本 1.00 |
| 4 | 0x00 | bCountryCode | 硬件设备所在国家的国家代码 0 = 通用/无国家键盘布局 |
| 5 | 0x01 | bNumDescriptors | 后面跟随下级描述符数量 |
| 6 | 0x22 | bDescriptorType | 类别描述符的类型0x22 = 报表描述符(Report)基本上鼠标、键盘、自定义 HID 都只用到 0x22 |
| 7-8 | 0x0022 | wDescriptorLength | 报表描述符总长度(小端)0x0022 = 34 字节 |
端点描述符
- 端点可以理解为逻辑上的数据传输通道,USB 设备往往需要同时进行多种互不干扰的数据传输,端点的概念使得USB可以根据数据不同的类型选择不同的传输方式,如USB耳机,音频数据可以使用某个端点实时传输,音量控制数据可以使用另外一个端点进行中断传输
| 偏移量 | 值 | 字段名 | 含义 |
|---|---|---|---|
| 0 | 0x07 | bLength | 长度 |
| 1 | 0x05 | bDescriptorType | 描述符类型 |
| 2 | 0x81 | bEndpointAddress | 端点地址,0x81为10000001,高位1为IN(设备到主机),低位1为端点1 |
| 3 | 0x03 | bmAttributes | 传输类型为中断传输 |
| 4-5 | 0x0040 | wMaxPacketSize | 最大包大小,0x40=64 |
| 6 | 0x01 | bInterval | 查询端点进行数据传输的间隔轮询间隔 1 帧(全速=1 ms) |



报表描述符
/*HID报表描述符*/
const uint8_t HIDDescr[] = { 0x06, 0x00,0xff,
0x09, 0x01,
0xa1, 0x01,//集合开始 0x09, 0x02,//Usage Page 用法
0x15, 0x00, //Logical Minimun
0x26, 0x00,0xff, //Logical Maximun
0x75, 0x08, //Report Size
0x95, 0x40, //Report Counet
0x81, 0x06, //Input
0x09, 0x02, //Usage Page
0x15, 0x00, //Logical Minimun
0x26, 0x00,0xff,//Logical Maximun
0x75, 0x08,//Report Size
0x95, 0x40, //Report Counet
0x91, 0x06, //Output
0xC0};
| 值 | 含义 |
|---|---|
| 0x06, 0x00,0xff | 设置当前的 Usage Page 为供应商自定义页 |
| 0x09, 0x01 | 设置当前 Usage 为 0x01(在此 Usage Page 下)。作用:定义一个用途,用于标识整个集合(Application Collection)的作用,例如“设备控制”。 |
| 0xa1, 0x01 | 开始一个应用集合,将后面的报表项分组,表示它们属于同一个应用。一个设备可以有多个应用集合(如键盘+鼠标) |
| 0x09, 0x02 | 再次设置当前 Usage 为 0x02。作用:用于接下来的 Input 和 Output 报表项,表示这些数据是属于“用途 2”(例如“数据传输”) |
| 0x15, 0x00 | 设置报表中每个字段的逻辑最小值为 0 |
| 0x26, 0x00,0xff | 设置逻辑最大值为 255 |
| 0x75, 0x08 | 告诉主机,每个数据单元的长度是 1 字节 |
| 0x95, 0x40 | 表示该报表共有 64 个字节,Report Size = 8 位 × Report Count = 64 |
| 0x81, 0x06 | 定义一个 Input 报表,设备可以通过此报表发送 64 字节的数据给主机(例如传感器数据、状态信息) |
| 0x09, 0x02 | |
| 0x15, 0x00 | |
| 0x26, 0x00,0xff | |
| 0x75, 0x08 | |
| 0x95, 0x40 | 机可以通过此报表发送 64 字节数据给设备(例如命令、配置、固件数据) |
| 0x91, 0x06 | 定义一个 Output 报表 |
| 0xC0 | 结束之前开启的 Application Collection |
标准 Usage Page 让主机自动识别设备类型(键盘、鼠标等)。供应商自定义 Usage Page(0xFF00 – 0xFFFF) 可以实现免驱动的自定义 HID 通信,是许多 USB 自定义设备(如调试器、固件升级工具)常用的方法


浙公网安备 33010602011771号