USB

概述

USB是“Universal Serial Bus”的缩写,中文意思是“通用串行总线”。它是一种广泛使用的接口技术,主要用于连接计算机与各种外部设备,如鼠标、键盘、打印机、摄像头、移动硬盘、手机等。主要特点:

  • 通用性强:USB接口被几乎所有类型的计算机(包括台式机、笔记本电脑、平板电脑等)和大量外部设备所支持,是一种通用的连接标准
  • 即插即用:大多数USB设备在连接到计算机后,操作系统可以自动识别并安装相应的驱动程序,无需用户进行复杂的配置
  • 支持热插拔:用户可以在不关闭计算机电源的情况下插拔USB设备,方便使用
  • 传输速度快:USB技术不断更新,从最早的USB 1.0到现在的USB 3.2和USB4,传输速度大幅提升。例如,USB 3.2的理论传输速度最高可达20Gbps
  • 支持多种设备连接:通过USB集线器,可以连接多个设备,扩展计算机的外设连接能力

USB技术发展

  • USB 1.x
    • USB 1.0
    • USB 1.1(即USB 2.0 Full Speed)
  • USB 2.0(即USB 2.0 High Speed)
  • USB 3.x
    • USB 3.0(即USB 3.2 Gen1)
    • USB 3.1(即USB 3.2 Gen2)
    • USB 3.2(即USB 3.2 Gen2*2)
image-20250902163917812
  • 低速:1.5Mbps
  • 全速:12Mbps
  • 高速:480Mbps
  • 超速:5G / 10G /20G bps

硬件接口

image-20250916105236218

image-20250902154128850

image-20250902154326310

协议规范

基本概念

  • USB主机:一个提供USB接口及接口管理能力的硬件、软件的复合体,一个USB系统中仅有一个USB主机,传输永远是主机先发起,设备响应
  • USB设备:分为集线器和功能设备,最多支持127个设备(usb设备使用7bit地址,范围0-127,0作为未初始化的设备使用
  • USB OTG:既能当主机又能当从机的设备,靠ID引脚决定角色。比如手机插 U 盘,手机是 Host;手机连 PC,手机是 Device
  • 上传:USB主机接收设备的数据
  • 下传:USB主机给设备发送数据
  • 地址:主机为每个从机都会分配一个地址,1个主机最多分配127个地址
  • 端点:USB中的实际物理单元,端点和地址决定了传输的物理通道

设备类型

USB设备有很多不同的类型,通过设备描述符的bDeviceClass或者接口描述符中的bInterfaceClass字段指定。多功能设备必须由后者指定

USB类别 描述 用途示例
00h 未指定(Use class information in Interface Descriptors) 设备类别由接口定义,可多功能设备
01h 音频(Audio) 声卡、麦克风、USB 音箱
02h 通信(Communications & CDC Control) USB 调制解调器、网络适配器
03h 人机接口设备(HID) 键盘、鼠标、游戏手柄、遥控器
05h 物理设备(Physical Interface Device, PID) 力反馈设备、传感器
06h 图像(Imaging) 扫描仪、数码相机、网络摄像头
07h 打印机(Printer) USB 打印机
08h 大容量存储(Mass Storage) U 盘、移动硬盘、SD 卡读卡器
09h 集线器(Hub) USB Hub
0Ah 数据(CDC-Data) 数据通信接口
0Bh 智能卡(Smart Card) 智能卡读卡器
0Dh 内容安全(Content Security) DRM 设备
0Eh 视频(Video) USB 摄像头、视频采集卡
0Fh 个人健康设备(Personal Healthcare Device) 血压计、心率监测器
DCh 诊断设备(Diagnostic Device) 医疗诊断设备
E0h 通用供应商特定(Wireless Controller) 蓝牙适配器、无线手柄
EFh 设备供应商特定(Miscellaneous) 联合类设备,多功能设备
FEh 应用专用(Application Specific) 工业设备、专用仪器
FFh 厂商自定义(Vendor Specific) 特殊定制设备

信号传输状态

  • J状态
  • K状态
  • SE0状态
  • SE1状态

定义:一个时间单位,固定为1ms(低/全速),125us(高速)

通讯的结构层次

  • 事务
  • 传输:USB支持4种传输,控制传输、中断传输、批量传输、等时传输
    • 控制传输:主要用于在设备连接时对设备进行枚举以及其他因设备而异的特定操作
    • 中断传输:用于对延迟要求严格、小量数据的可靠传输,如键盘、游戏手柄等
    • 批量传输:用于对延迟要求宽松,大量数据的可靠传输,如U盘等
    • 同步传输:用于对可靠性要求不高的实时数据传输,如USB摄像头、USB音响等

多个域组成一个包;多个包组成一个事务;多个事务组成一个传输

描述符

USB只是一个数据通路,USB总线驱动程序需要知道对端设备情况,就需要读取相关信息,引出了:设备、配置、接口和端点4个层次。这4个层次是所有USB设备都有的,所以他们的描述符也叫标准描述符

对象 定义
Device 一台多功能设备(比如“USB 摄像头 + 麦克风”)
Configuration 工作模式(比如“正常模式”或“低功耗模式”)
Interface 功能模块(视频模块、音频模块)
Endpoint 数据通道(传输实际视频帧或音频流)
Unit 模块内部的信号处理节点(亮度调节、音量调节)

Endpoint和Unit的区别是什么

  • Unit是UVC协议引入的概念,它描述了相机内部视频信号的逻辑路径,而数据在不同的USB Interface之间传输,靠的还是Endpoint

标准描述符

1.设备描述符(只有一个): 整个设备的身份信息(厂商ID、产品ID、协议版本等)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct usb_device_descriptor {
uint8_t bLength; // 长度 = 18
uint8_t bDescriptorType; // 类型 = DEVICE (0x01)
uint16_t bcdUSB; // USB 版本号,如 0x0200 表示 USB2.0
uint8_t bDeviceClass; // 设备类(如 0xEF 表示复合设备)
uint8_t bDeviceSubClass;
uint8_t bDeviceProtocol;
uint8_t bMaxPacketSize0; // 端点0(控制端点)最大包长
uint16_t idVendor; // 厂商ID(VID)
uint16_t idProduct; // 产品ID(PID)
uint16_t bcdDevice; // 设备版本号
uint8_t iManufacturer; // 厂商字符串描述符索引
uint8_t iProduct; // 产品字符串描述符索引
uint8_t iSerialNumber; // 序列号字符串索引
uint8_t bNumConfigurations; // 支持的配置数量
};

主机通过读取它,知道:

  • 设备属于哪个类(比如音频、视频、HID、存储)
  • VID/PID 用于驱动匹配
  • 支持几个配置(Configuration)

2.配置描述符(至少有一个):描述一个完整的工作模式配置(供电要求、接口数、属性等)

1
2
3
4
5
6
7
8
9
10
struct usb_config_descriptor {
uint8_t bLength; // 长度 = 9
uint8_t bDescriptorType; // CONFIGURATION (0x02)
uint16_t wTotalLength; // 本配置下所有描述符的总长度
uint8_t bNumInterfaces; // 本配置下的接口数量
uint8_t bConfigurationValue; // 该配置编号
uint8_t iConfiguration; // 字符串描述符索引
uint8_t bmAttributes; // 电源属性(总线供电/自供电/远程唤醒)
uint8_t bMaxPower; // 最大电流(单位:2mA)
};

一个配置下通常紧跟着多个 Interface 描述符

3.接口描述符(至少有一个):描述一个功能接口(属于哪个类、包含多少端点),一个接口就是实现一种功能。

1
2
3
4
5
6
7
8
9
10
11
struct usb_interface_descriptor {
uint8_t bLength;
uint8_t bDescriptorType; // INTERFACE (0x04)
uint8_t bInterfaceNumber; // 接口号
uint8_t bAlternateSetting; // 备用设置号(常用于带带宽变化的流)
uint8_t bNumEndpoints; // 除端点0外的端点数量
uint8_t bInterfaceClass; // 类代码
uint8_t bInterfaceSubClass; // 子类
uint8_t bInterfaceProtocol; // 协议代码
uint8_t iInterface; // 字符串索引
};

每个 Interface 通常包含若干 Endpoint,在视频/音频设备中,一个 Interface 表示一种独立的功能(如视频流输出接口)

4.端点描述符(至少有一个):描述接口中的每个端点的传输属性(方向、类型、包大小等)

  • 端点是实现USB设备功能的物理缓冲区实体,USB主机和设备是通过端点进行数据交互的
1
2
3
4
5
6
7
8
struct usb_endpoint_descriptor {
uint8_t bLength;
uint8_t bDescriptorType; // ENDPOINT (0x05)
uint8_t bEndpointAddress; // 位7方向:0=OUT,1=IN;低4位端点号
uint8_t bmAttributes; // 传输类型:控制/批量/中断/同步
uint16_t wMaxPacketSize; // 最大包大小
uint8_t bInterval; // 轮询间隔(中断/同步传输用)
};

一个接口可以有多个端点,例如:

  • IN 端点:设备 → 主机(如摄像头视频流)
  • OUT 端点:主机 → 设备(如控制命令)
image-20250902161527786
1
2
3
4
5
6
7
8
9
10
Device Descriptor
├── Configuration Descriptor (Config #1)
│ ├── Interface Association Descriptor (optional)
│ ├── Interface Descriptor #0
│ │ ├── Endpoint Descriptor #1
│ │ └── Endpoint Descriptor #2
│ └── Interface Descriptor #1
│ ├── Endpoint Descriptor #3
│ └── Endpoint Descriptor #4
└── Configuration Descriptor (Config #2)

5.字符串描述符:用于描述人类可读的字符串(厂商名、产品名、序列号等)

1
2
3
4
Index 0: [0x09, 0x04] → 表示语言是 English (US)
Index 1: "Manufacturer"
Index 2: "Product Name"
Index 3: "Serial Number"

6.接口关联描述符:某些设备(如视频+音频摄像头)有多个接口共同构成一个功能单元,此描述符用于将它们逻辑上“绑定”在一起

1
2
3
4
5
6
7
8
9
10
struct usb_interface_assoc_descriptor {
uint8_t bLength; // 8
uint8_t bDescriptorType; // INTERFACE ASSOCIATION (0x0B)
uint8_t bFirstInterface; // 第一个接口号
uint8_t bInterfaceCount; // 接口数量
uint8_t bFunctionClass; // 功能类(如视频)
uint8_t bFunctionSubClass;
uint8_t bFunctionProtocol;
uint8_t iFunction; // 功能字符串索引
};

类特定描述符

定义:针对某个USB类定义的扩展描述符,用来描述该类设备特有的功能和属性。它并不是标准的 USB 描述符,而是类规范(如 HID、Audio、Video)定义的额外信息

典型类特定描述符 说明
HID HID Descriptor 描述报告格式
Audio Audio Control / Audio Streaming 描述音频拓扑、采样率、声道
Video Video Control / Video Streaming 描述视频拓扑、帧率、格式等
  • 描述UVC中的unit的,其实就是类特定描述符

类特定描述符一般依附于标准描述符出现,比如

1
2
3
4
5
6
7
8
9
Device Descriptor
└── Configuration Descriptor
├── Interface Descriptor (VC)
├── Class-Specific VC Descriptor
│ ├── Input Terminal Unit
│ ├── Processing Unit
│ └── Output Terminal Unit
└── Endpoint Descriptor (Interrupt IN)
└── Class-Specific Endpoint Descriptor

热插拔检测

USB的热插拔是由主机进行检测的

  • 低速或者全速设备:USB设备的主机端,D+和D-都是下拉,而设备端会上拉D+或者D-,如果主机端检测到D+/D-被上拉,就知道有设备被插入了,并且根据上拉的是D+还是D-可以知道是全速设备还是低速设备
  • 高速设备:先以全速设备和主机相连,然后做双向检测,满足条件后进入高速模式

断开检测:主机检测到D+/D-都是低电平超过2.5us

总线状态

  • 正常工作
  • 总线复位
  • 总线挂起

USB枚举

定义:USB主设备向USB从设备通过获取各种描述符,了解设备的基本描述信息,如支持的 USB 版本、Product ID、Vendor ID、设备分类(Class)、供电方式、最大消耗电流、配置数量、各种类型端点的数量及传输能力(最大包长度)。HOST根据PID和VID加载设备驱动程序,并对设备进行合适的配置。只有经过枚举的设备才能正常使用。对于总线供电设备,在枚举完成前最多可从总线获取100mA的电流

只有枚举完成并确认设备信息后,内核才会去匹配并调用对应驱动的 probe()

特点:

  • 主设备连接识别从设备必须的过程
  • 由多个控制传输构成
  • 经过地址0(缺省地址)到其他地址(主设备分配地址)的通讯
  • 对于挂载多个USB从设备的系统,主设备是逐一进行枚举操作

枚举过程:

设备插入->主机检测->总线复位->分配地址->获取设备描述符->获取配置描述符->选择配置

1.USB设备上电(一般从USB口取电)并连接到USB总线

2.主机检测到总线上有设备连接

3.主机会等待至少100ms用于连接的机械、电气特性稳定

4.主机执行总线复位至少10ms,并得到USB设备通讯速度

5.主机驱动总线空闲至少10ms用于做恢复时间

6.主机发出获取设备描述符请求(0地址)

7.主机为从设备分配唯一设备地址,后续通讯用此地址

8.主机以新地址发出获取设备描述符请求

9.主机以新地址发出获取配置描述符请求,获取设备全部配置

10.主机分析获取的描述符信息,并做相应记录和处理

11.主机发送设置配置请求,为从设备选择一个合适的配置

驱动框架