USB_基础概念

{3CB50F53-9CF3-4073-A44E-6631EFBE0A67}

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

通信过程

{1AB4B847-E29A-4657-AD74-F3E9E848B0FC}

  • 域是最底层的信息单元,多个域组成一个包,类似组成完整句子的单词
  • 同步域(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 该设备支持的配置描述符数量

9565453d-30d7-40b6-acde-0ea31e8d596f

配置描述符

// 配置描述符
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)

8311d98d-77db-4f5e-ad1d-ff7ed95ee867
6bab6caa-d171-4bec-87f8-9ce31eb2f5cc
6e59fe67-6645-4ba5-8703-4cb2d01ab7b1

报表描述符

/*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 自定义设备(如调试器、固件升级工具)常用的方法
{375D84CB-1924-469E-B92F-4F22F9CC2F85}

posted @ 2026-06-23 11:00  J_02346  阅读(37)  评论(0)    收藏  举报