news 2026/1/31 0:35:46

USB协议原理梳理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
USB协议原理梳理

USB协议核心知识

一、USB协议架构

1.1 协议分层

USB协议采用分层架构设计,从下至上分为物理层、链路层、协议层、应用层,各层独立封装,降低开发复杂度。

1.1.1 物理层

定义USB接口的硬件特性,包括引脚定义、电压等级、传输速率等。

  • USB 2.0:支持低速(1.5Mbps)、全速(12Mbps)、高速(480Mbps)
  • USB 3.x:新增超高速(5Gbps)、超高速+(10Gbps)模式,引脚数量与信号定义更复杂
1.1.2 链路层

负责数据的编码/解码、差错检测与纠正、数据包的收发控制。

  • 采用差分信号传输
  • 通过NRZI编码方式提升抗干扰能力
  • 支持CRC校验确保数据完整性
1.1.3 协议层

定义USB的核心通信协议,包括设备枚举、端点配置、数据传输类型、控制命令等,是开发调试的核心关注层。

核心作用

  • 将应用层的功能需求转化为可在总线上传输的标准化数据包
  • 解析总线上接收的数据包并向上层反馈
  • 作为物理层/链路层与应用层的桥梁
  • 直接决定设备与主机的通信兼容性和稳定性
1.1.4 应用层

针对不同USB设备类(如HID、CDC、存储类等)定义的专用协议规范,决定设备的具体功能实现。


1.2 协议层核心定义

协议层的核心是围绕"数据包交互"构建的规则体系。

1.2.1 数据包结构

所有USB通信均以数据包为单位,协议层定义了统一的基础字段格式,同时针对不同类型数据包扩展专属字段。

USB数据包基础结构(通用框架)
字段长度取值范围/固定值核心功能
同步字段(SYNC)8位(1字节)固定值:0x80时钟同步,数据包起始标识
包标识符(PID)8位(1字节)类型码4位+校验码4位包类型标识
地址字段(ADDR)7位0~127设备寻址
端点字段(ENDP)4位0~15端点寻址
数据字段(DATA)可变上限:64/1024字节承载业务数据
校验字段(CRC)5位/16位-数据完整性校验
结束字段(EOP)3位2低+1高包结束标识

说明

  1. 地址字段(ADDR)与端点字段(ENDP)仅存在于令牌包中,DATA包、握手包无这两个字段
  2. 数据字段(DATA)仅存在于SETUP令牌包和DATA包中,其他类型包无此字段
  3. 校验字段(CRC)的类型与长度随包类型变化

1.2.2 各字段详细定义
1.2.2.1 同步字段(SYNC)
  • 长度:8位(1字节)
  • 固定值:0x80(二进制10000000)
  • 功能
    • 同步主机与设备的时钟频率
    • 确保双方对后续数据的采样时序一致
    • SYNC字段是数据包的起始标识
    • 设备检测到该字段后开始准备接收后续数据
1.2.2.2 包标识符(PID)
  • 长度:8位
  • 结构:“4位类型码 + 4位校验码”
  • 校验码:为类型码的反码(用于校验PID传输正确性)

根据PID值,数据包分为三大类:

数据包类型常见PID值(十六进制)类型码(二进制)核心功能
令牌包(Token)IN(69)、OUT(E1)、SETUP(2D)、SOF(A5)对应类型编码发起传输请求,指定方向、地址、端点
数据包(Data)DATA0(C3)、DATA1(4B)、DATA2(87)、MDATA(0F)对应类型编码承载实际业务数据,支持交替重传机制
握手包(Handshake)ACK(D2)、NAK(5A)、STALL(1E)、NYET(96)对应类型编码反馈传输结果,无数据字段

  • SOF仅适用于USB 2.0低速/全速模式
  • NYET为高速模式专属

各类型详细说明

令牌包(Token Packet)

  • 用于发起一次传输请求
  • 告知设备传输方向、地址及端点
  • 常见PID:
    • IN(0x69):主机从设备读取数据
    • OUT(0xE1):主机向设备写入数据
    • SETUP(0x2D):主机向设备发送控制命令
    • SOF(0xA5):帧起始标记,仅USB 2.0低速/全速模式,用于同步帧周期

数据包(Data Packet)

  • 用于承载实际数据
  • 仅在令牌包发起后传输
  • 无令牌包前置时设备会忽略DATA包
  • 常见PID:
    • DATA0(0xC3)
    • DATA1(0x4B)
    • DATA2(0x87):高速模式
    • MDATA(0x0F):高速模式
  • 用于支持批量传输和等时传输的数据包交替机制(解决数据重传时的歧义)

握手包(Handshake Packet)

  • 用于反馈传输结果
  • 无数据字段
  • 仅作为响应包存在,不能主动发起
  • 常见PID:
    • ACK(0xD2):确认数据接收成功
    • NAK(0x5A):设备忙无法接收/发送数据,主机需重试
    • STALL(0x1E):设备功能异常或不支持该请求,需主机查询状态
    • NYET(0x96):高速模式专属,告知主机无需重试
1.2.2.3 地址字段(ADDR)
  • 长度:7位
  • 取值范围:0~127
  • 功能:标识总线上的USB设备

特性

  • 地址0为默认地址,仅用于设备枚举阶段(复位后设备默认使用地址0)
  • 枚举完成后主机为设备分配唯一的非0地址
  • 地址字段仅存在于令牌包中
  • DATA包和握手包无此字段(依赖前置令牌包的地址信息定位设备)
1.2.2.4 端点字段(ENDP)
  • 长度:4位
  • 取值范围:0~15
  • 功能:标识设备上的具体端点

特性

  • 端点0为控制端点,所有设备必带,用于枚举和控制命令交互
  • 其他端点为功能端点,需通过描述符定义属性
  • ENDP字段与ADDR字段组合,实现"设备-端点"的精准寻址
  • 仅存在于令牌包中
1.2.2.5 数据字段(DATA)
  • 长度:可变
  • 限制:需符合对应端点的最大数据包大小限制
  • 适用范围:仅存在于DATA包和SETUP令牌包中

不同类型的数据字段

SETUP包数据字段

  • 固定为8字节
  • 结构如下:
字段长度字节序说明
请求类型1字节-请求方向、类型、接收方
请求码1字节-具体的命令代码
2字节Little-Endian命令参数
索引2字节Little-Endian索引/偏移量
长度2字节Little-Endian数据长度

DATA包数据字段

  • 承载实际业务数据(如描述符内容、传感器数据、文件数据等)
  • 高速模式下最大长度为1024字节
  • 全速/低速模式下最大为64字节
1.2.2.6 校验字段(CRC)

分为CRC5和CRC16两种,根据数据包类型选择:

适用数据包类型校验长度校验覆盖范围核心作用
令牌包(IN/OUT/SETUP)5位ADDR字段+ENDP字段校验寻址信息正确性
DATA包16位整个数据字段校验业务数据完整性

特性

  • CRC校验由发送方计算生成,接收方验证
  • 若校验失败则丢弃数据包,触发重传(等时传输除外)
1.2.2.7 结束字段(EOP)
  • 长度:2位低电平+1位高电平
  • 功能:标识数据包结束

特性

  • 设备检测到EOP后停止数据接收,完成一次数据包处理
  • EOP字段由硬件自动生成,无需固件/驱动干预
  • 传输过程中EOP信号异常会导致数据包丢失

1.2.3 数据包交互逻辑

USB总线交互以"令牌包-数据包-握手包"的三段式流程为核心(部分传输类型简化),遵循"主机主导、设备响应"的原则。

1.2.3.1 基础交互规则

1. 交互发起

  • 所有交互由主机发起
  • 主机通过发送令牌包(IN/OUT/SETUP)指定传输方向、目标设备及端点
  • 开启一次传输周期
  • 设备通过持续监测总线,解析SYNC和PID字段
  • 当检测到匹配自身地址和端点的令牌包时,开始响应
  • 否则忽略该令牌包及后续数据包

2. 数据传输

根据令牌包类型执行对应数据传输:

令牌包类型传输流程数据流向
SETUP主机发送8字节DATA包 → 设备接收 → 设备返回握手包主机→设备
OUT主机发送DATA包 → 设备接收校验CRC16 → 设备返回ACK主机→设备
IN设备发送DATA包 → 主机接收校验 → 主机返回ACK设备→主机

特性

  • SETUP令牌包后,主机立即发送8字节DATA包(控制命令参数)
  • 设备接收SETUP数据后无需返回DATA包,直接反馈握手包
  • OUT传输校验成功后返回ACK,失败则不返回握手包(主机超时后重试)
  • IN传输主机校验成功后返回ACK,失败则不返回(设备超时后重试)

3. 握手反馈

握手包是传输结果的唯一反馈,主机根据设备返回的握手包调整后续操作:

握手包类型含义主机后续操作
ACK确认数据接收成功结束本次传输,进入下一次传输周期
NAK设备忙无法接收/发送数据等待预设时间后重新发送令牌包,重试次数由固件/驱动配置
STALL设备功能异常或不支持该请求停止传输,发起"获取设备状态"命令,排查异常原因
无握手包超时判定为超时,触发重传或报错

4. 帧同步(低速/全速模式)

  • 主机每1ms发送一次SOF令牌包(PID=0xA5)
  • SOF包包含帧编号(11位)
  • 用于同步设备的中断传输周期和等时传输带宽分配
  • 设备根据SOF包的帧编号调整自身数据发送时序
  • 确保实时性传输的稳定性
  • 高速模式下无SOF包,通过总线时钟同步时序

5. 异常处理

传输过程中若出现以下问题,接收方会丢弃数据包,不返回握手包:

  • CRC校验失败
  • EOP信号异常
  • 数据长度超限

主机检测到超时(默认超时时间为10ms~50ms)后:

  • 会重新发起令牌包重试
  • 重试次数达到阈值后判定传输失败
  • 向上层返回错误信息

等时传输因无重传机制,校验失败则直接丢弃数据,优先保证传输速率。


1.2.4 不同传输类型的数据包交互差异
1.2.4.1 控制传输

采用"SETUP阶段 + DATA阶段 + Status阶段"三段式交互:

阶段交互内容说明
SETUP阶段SETUP令牌包 + 8字节DATA包 + ACK握手包发送控制命令
DATA阶段IN/OUT令牌包 + DATA包 + ACK握手包(可选)传输数据,无数据时跳过
Status阶段反向握手(设备向主机发送状态数据)确认配置完成

特性

  • 全程依赖端点0
  • 优先级最高,可抢占其他传输类型的总线资源
1.2.4.2 中断传输
  • 主机按预设周期(通过端点描述符配置,1ms~255ms)发送IN令牌包
  • 设备响应DATA包,主机返回ACK
  • 若设备无数据则返回NAK,主机下周期重试
  • 无STALL反馈(中断设备异常时直接停止响应)
  • 适用于小量实时数据传输
1.2.4.3 批量传输
  • 主机在总线空闲时发送IN/OUT令牌包
  • 设备响应DATA包,主机返回ACK
  • 若设备忙则返回NAK,主机等待总线空闲后重试
  • 支持DATA0/DATA1交替机制,解决重传歧义
  • 无固定传输周期,优先保证数据完整性
  • 适用于大量非实时数据传输
1.2.4.4 等时传输
  • 主机按固定周期发送IN/OUT令牌包
  • 设备响应DATA包,无握手包反馈(不校验CRC,不重传)
  • 占用固定总线带宽,传输速率稳定
  • 适用于音视频等实时性要求极高的场景
  • 允许少量数据丢失

1.2.5 设备地址与端点管理

地址管理

  • 协议层规定主机为每个接入设备分配唯一的7位地址(0~127)
  • 默认地址0用于枚举阶段
  • 枚举完成后使用分配的唯一地址通信

端点管理

  • 每个设备支持最多16个端点(0~15)
  • 端点0固定为控制端点,用于枚举和控制命令交互
  • 其他端点需通过描述符定义传输类型、方向、数据包大小等属性
  • 协议层负责端点的寻址和数据路由

1.2.6 控制命令集

协议层定义了标准化的控制命令,主机通过这些命令完成设备枚举、配置、状态查询等操作:

核心命令功能说明
获取描述符(Get Descriptor)读取设备描述符信息
设置地址(Set Address)为设备分配USB地址
设置配置(Set Configuration)选择设备配置
获取状态(Get Status)查询设备状态
  • 命令通过SETUP令牌包发起
  • 配合数据和握手包完成交互

1.2.7 传输时序规则

协议层明确了不同传输类型的时序逻辑:

传输类型时序规则目的
控制传输三阶段(Setup、Data、Status)时序确保配置的完整性
中断传输主机查询周期满足实时性要求
批量传输总线空闲抢占机制保证数据完整性
等时传输固定带宽分配规则确保传输速率稳定

这些规则确保多种传输类型在同一总线上有序共存,避免冲突。


1.3 协议层实现要点

协议层的实现需依托硬件(USB控制器)和固件/驱动的协同。

1.3.1 USB控制器驱动适配

固件侧

  • 配置USB控制器的寄存器
  • 使能对应的传输模式、端点属性、数据包大小
  • 绑定端点中断服务函数(ISR)

主机侧驱动

  • 识别USB控制器类型
  • 对接协议层的数据包收发接口
  • 实现地址分配、命令下发等逻辑
1.3.2 数据包收发与解析

固件侧

  • 通过USB控制器的FIFO缓冲区接收和发送数据包
  • 在中断服务函数中解析PID,区分令牌包、数据包和握手包
  • 根据命令类型执行对应操作
  • 示例:接收SETUP命令后读取描述符并返回

主机侧

  • 通过控制器接口发起令牌包
  • 等待设备返回数据包或握手包
  • 处理重传、STALL等异常情况
1.3.3 枚举流程的协议适配

固件侧

  • 需严格按照协议层定义的枚举时序
  • 在不同阶段响应主机的命令
  • 示例:
    • 复位后准备好设备描述符
    • 地址分配后切换至新地址响应配置描述符请求

主机侧

  • 需遵循枚举步骤,逐步获取描述符并完成配置
  • 处理枚举过程中的超时、描述符错误等异常
1.3.4 异常处理机制

协议层需实现标准化的异常处理:

设备侧响应含义主机侧处理
NAK设备忙需重试
STALL功能异常需查询设备状态

同时需处理总线复位、设备断开等突发情况,确保通信链路的稳定性。


1.4 典型例子:HID设备枚举的协议层交互过程

以常见的USB键盘(HID类设备)为例,说明协议层在枚举过程中的具体交互实现。

1.4.1 复位阶段
  • 主机检测到键盘接入后
  • 通过D+引脚发送复位信号(低电平保持10ms以上)
  • 协议层触发设备侧USB控制器复位
  • 设备恢复默认状态
    • 地址设为0
    • 仅端点0使能
    • 等待主机命令
1.4.2 获取设备描述符

主机发送

  • SETUP令牌包(PID=SETUP,ADDR=0,ENDP=0)
  • 携带"获取设备描述符"命令
    • 请求类型=0x80
    • 请求码=0x06
    • 值=0x0000
    • 索引=0x0000
    • 长度=0x0012

设备响应

  • 设备侧端点0中断触发
  • 解析SETUP数据包
  • 从固件缓冲区读取18字节设备描述符
  • 通过DATA1数据包返回
    • 包含VID=0x0483
    • PID=0x5750
    • 设备类=0x00(接口类定义)等信息

主机确认

  • 主机接收后返回ACK握手包
  • 确认数据接收成功
1.4.3 分配地址

主机发送

  • SETUP令牌包
  • 携带"设置地址"命令
    • 请求类型=0x00
    • 请求码=0x05
    • 值=0x0001
    • 索引=0x0000
    • 长度=0x0000

设备响应

  • 设备解析命令后
  • 将USB控制器的地址寄存器设为1
  • 返回ACK握手包

后续通信

  • 后续主机与设备的通信均使用地址1
1.4.4 获取配置描述符

主机发送

  • SETUP令牌包
  • 携带"获取配置描述符"命令
    • 请求类型=0x80
    • 请求码=0x06
    • 值=0x0200
    • 索引=0x0000
    • 长度=0x0029

设备返回

  • 配置描述符(9字节)
    • 含供电方式、最大电流、接口数量=1
  • 接口描述符(9字节)
    • 含接口类=0x03(HID类)
    • 端点数量=1
  • HID类描述符(16字节)
    • 含HID版本、报告描述符长度
  • 端点描述符(7字节)
    • 含端点1、中断输入
    • 最大数据包大小=8
    • 查询周期=10ms

主机确认

  • 主机接收后返回ACK
  • 确认描述符获取完成
1.4.5 设置配置

主机发送

  • SETUP令牌包
  • 携带"设置配置"命令
    • 请求类型=0x00
    • 请求码=0x09
    • 值=0x0001
    • 索引=0x0000
    • 长度=0x0000

设备响应

  • 设备解析命令后
  • 启用接口1和端点1
  • 配置中断传输参数
  • 返回ACK握手包
  • 完成枚举进入工作状态
1.4.6 总结

上述过程中,协议层全程主导交互逻辑:

  • 主机侧协议层按枚举时序下发标准化命令
  • 设备侧协议层解析命令并返回合规数据
  • 双方通过PID识别数据包类型
  • 通过握手包确认交互状态
  • 严格遵循地址分配、描述符交互、配置启用的协议规则
  • 最终实现设备与主机的通信建立

若协议层实现存在偏差(如描述符长度错误、地址切换延迟),会导致枚举失败,设备无法被主机识别。


1.5 设备枚举流程

USB设备接入主机后,需完成枚举流程才能建立正常通信,枚举是开发调试中易出问题的环节。

1.5.1 枚举核心步骤
步骤操作说明
1. 设备上电USB设备接入主机后,主机通过VBUS引脚为设备供电(标准USB端口提供5V/500mA,USB 3.x可提供更多功率)
2. 主机检测主机通过D+、D-引脚的电平变化检测到新设备接入(低速/全速设备拉低D-,高速设备先拉低D-,协商后切换至高速模式)
3. 复位设备主机向设备发送复位信号,设备进入默认状态,使用默认端点0(控制端点)进行通信
4. 读取设备描述符主机通过端点0读取设备的设备描述符,获取VID、PID、设备类等基础信息
5. 分配地址主机为设备分配唯一的USB地址,设备后续使用该地址进行通信
6. 读取配置描述符主机读取设备的配置描述符、接口描述符、端点描述符,了解设备的配置选项、接口数量及端点属性(传输类型、数据包大小等)
7. 设置配置主机根据设备描述符信息,选择合适的配置并发送设置命令,设备进入配置状态,完成枚举

二、USB传输类型

USB协议定义了四种传输类型,适用于不同的应用场景,开发时需根据需求选择对应的传输类型及端点配置。

2.1 传输类型对比

传输类型核心特性数据包大小典型应用场景优先级
控制传输(Control)枚举、配置修改、命令交互,双向传输端点0设备枚举、控制命令最高
批量传输(Bulk)大量数据传输,对实时性要求低,但要求数据完整性,支持重传高速512字节/USB 3.x 1024字节U盘、打印机中等
中断传输(Interrupt)小量数据的实时传输,固定查询周期,支持重传描述符定义键盘、鼠标、传感器中等
等时传输(Isochronous)实时性要求极高的大量数据传输,无重传和CRC校验,允许数据丢失高速1023字节摄像头、音频设备低(等时优先)

2.2 各传输类型详细说明

2.2.1 控制传输(Control Transfer)
  • 用于设备枚举、配置修改、命令交互等核心操作
  • 具有最高优先级,支持双向传输
  • 依赖端点0实现
  • 传输过程分为Setup阶段、Data阶段(可选)、Status阶段
2.2.2 批量传输(Bulk Transfer)
  • 适用于大量数据传输
  • 对实时性要求低,但要求数据完整性
  • 支持CRC校验和重传机制
  • 常见于U盘、打印机等设备
  • USB 2.0高速模式下批量端点最大数据包大小为512字节
  • USB 3.x可提升至1024字节
2.2.3 中断传输(Interrupt Transfer)
  • 适用于小量数据的实时传输
  • 主机定期查询设备端点获取数据
  • 具有固定的查询周期
  • 支持重传
  • 常见于键盘、鼠标、传感器等HID设备
  • 中断端点的最大数据包大小和查询周期需在描述符中定义
2.2.4 等时传输(Isochronous Transfer)
  • 适用于实时性要求极高的大量数据传输
  • 不支持重传和CRC校验
  • 允许数据丢失,优先保证传输速率
  • 常见于摄像头、音频设备等
  • USB 2.0高速模式下等时端点最大数据包大小为1023字节

三、USB描述符

USB描述符是设备向主机汇报自身属性的核心数据结构,主机通过读取描述符了解设备信息并完成配置。

3.1 常见描述符类型

描述符类型长度核心内容
设备描述符(Device Descriptor)固定18字节VID、PID、设备类、子类、协议、端点0最大数据包大小、配置数量等
配置描述符(Configuration Descriptor)固定9字节配置编号、供电方式(总线供电/自供电)、最大电流、接口数量等
接口描述符(Interface Descriptor)固定9字节接口编号、端点数量、接口类/子类/协议等
端点描述符(Endpoint Descriptor)固定7字节端点地址(方向+编号)、传输类型、同步类型、最大数据包大小、查询周期等
字符串描述符(String Descriptor)不固定设备名称、厂商名称、接口名称等字符串信息,支持多语言

3.2 描述符注意事项

  1. 格式严格:描述符的字段顺序、数据长度、取值范围必须严格遵循USB协议规范
  2. 参数合理:描述符中的参数(如数据包大小、查询周期)需符合实际硬件能力
  3. 兼容性:描述符格式错误会导致主机无法识别设备或枚举失败
  4. 顺序正确:描述符的返回顺序需符合协议要求(如设备描述符→配置描述符→接口描述符→端点描述符)

文档版本: 1.0
最后更新: 2026-01-28

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/28 18:50:47

高性能计算异构编程

1、非修改序列算法 这些算法不会改变它们所操作的容器中的元素。 1.1 find 和 find_if find(begin, end, value):查找第一个等于 value 的元素,返回迭代器(未找到返回 end)。find_if(begin, end, predicate):查找第…

作者头像 李华
网站建设 2026/1/28 18:50:39

自定义内存检测工具

1、非修改序列算法 这些算法不会改变它们所操作的容器中的元素。 1.1 find 和 find_if find(begin, end, value):查找第一个等于 value 的元素,返回迭代器(未找到返回 end)。find_if(begin, end, predicate):查找第…

作者头像 李华
网站建设 2026/1/30 5:30:28

Python性能优化技巧:让你的代码飞起来

SQLAlchemy是Python中最流行的ORM(对象关系映射)框架之一,它提供了高效且灵活的数据库操作方式。本文将介绍如何使用SQLAlchemy ORM进行数据库操作。目录安装SQLAlchemy核心概念连接数据库定义数据模型创建数据库表基本CRUD操作查询数据关系操…

作者头像 李华
网站建设 2026/1/29 21:15:18

分布式计算C++库

1、非修改序列算法 这些算法不会改变它们所操作的容器中的元素。 1.1 find 和 find_if find(begin, end, value):查找第一个等于 value 的元素,返回迭代器(未找到返回 end)。find_if(begin, end, predicate):查找第…

作者头像 李华
网站建设 2026/1/30 15:55:46

定时任务专家:Python Schedule库使用指南

SQLAlchemy是Python中最流行的ORM(对象关系映射)框架之一,它提供了高效且灵活的数据库操作方式。本文将介绍如何使用SQLAlchemy ORM进行数据库操作。目录安装SQLAlchemy核心概念连接数据库定义数据模型创建数据库表基本CRUD操作查询数据关系操…

作者头像 李华
网站建设 2026/1/29 20:17:34

内存泄漏检测与防范

1、非修改序列算法这些算法不会改变它们所操作的容器中的元素。1.1 find 和 find_iffind(begin, end, value):查找第一个等于 value 的元素,返回迭代器(未找到返回 end)。find_if(begin, end, predicate):查找第一个满…

作者头像 李华