资讯动态

USB2.0协议核心概念详解:速率、端点、传输类型与枚举流程

发布时间:2026/10/3 7:43:29 来源:尧图企业网站定制
先说一个可能有点反直觉的结论USB3.x、USB4、雷电接口已经喊了好多年但USB2.0依然是这个星球上活得最滋润的接口标准之一。你桌面上的键盘、鼠标、无线接收器开发板上的调试口打印机的控制通道甚至很多工业设备里的固件升级接口底层跑的还是USB2.0那一套协议。做嵌入式、做驱动、做硬件设计的人迟早要跟它打交道。这篇是USB2.0学习系列的第一篇聚焦基本概念把速率体系、物理层、协议层、拓扑结构、枚举流程这些骨架性的东西讲清楚。我不打算一上来就贴大段寄存器表而是想把整个USB2.0的工作机制串成一条线让你读完能回答三个问题USB2.0到底分几种速度设备插上去之后主机是怎么“认出”它的数据在主机和设备之间究竟怎么流动适合刚接触USB协议的同学建立整体框架也适合写过几笔USB代码、但始终没把“端点、管道、传输类型、枚举”这些概念理清的人来一次系统性查漏补缺。1. 速度分级与“双线信号”的底层逻辑1.1 三种速率真的不是同一套图纸USB2.0这个叫法很容易让人误以为它是一个单一速率的标准实际上它规定了三种完全不同的速率档位只是共享同一套协议框架和物理连接器速率名称比特率典型设备帧周期Low Speed低速1.5 Mbps鼠标、键盘、部分HID设备1 msFull Speed全速12 Mbps音频设备、旧款U盘、HID升级版1 msHigh Speed高速480 MbpsU盘、移动硬盘、网卡、摄像头125 μs微帧继续说个经常被忽略的细节低速和全速共用同一套信号编码方式而高速模式的电气层和信号握手流程是单独设计的。也就是说USB2.0不是简单地把全速时钟提高40倍而是当主机和设备都确认对方支持高速之后会通过一套“握手”流程把链路切换到高速模式。这个过程叫Chirp握手后面枚举部分我会详细拆。很多人以为“USB2.0480Mbps”这个理解在销售话术里没错但在协议层面上不严谨。一个宣称USB2.0兼容的设备大概率只是全速12Mbps尤其是大量廉价的HID类设备。真正跑在480Mbps高速模式的通常是对带宽有硬性需求的存储、视频采集和网络设备。搞开发之前先搞清楚目标设备的速率档位能避免后面一系列排查误区。1.2 连接器、引脚定义与线缆选型标准USB2.0连接器有Type-A和Type-B两种大接口后来又衍生出Mini和Micro等小型化版本但引脚定义始终是同一套4线方案引脚名称颜色常见作用1VBUS红5V电源2D−白数据负3D绿数据正4GND黑地这4根线背后有一套很聪明的设计哲学数据和电源共用一根线缆设备可以从总线上取电总线供电也可以自带电源。VBUS默认能提供500mA电流但要注意这是标准值实际很多主板的USB口能输出更多而一些劣质集线器连500mA都保证不了接大功率设备时会出现电压跌落。D/D−是一对差分信号线规范要求特性阻抗90Ω±15%所以USB2.0高速模式的PCB走线必须做差分阻抗控制。我见过不少新手画板子的时候把D/D−当成普通信号线随意走结果高速设备插上去要么枚举失败要么传输速率异常。对此我的经验是USB2.0高速模式下D/D−走线尽量等长、靠近、远离干扰源过孔数量尽量少线缆则建议选用带屏蔽层的合格线劣质线缆往往在高速模式下直接罢工。1.3 信号编码NRZI与位填充低速和全速模式下数据不是简单地用高低电平表示1和0而是用NRZI反向不归零编码。NRZI的规则是遇到逻辑0时信号电平翻转遇到逻辑1时信号电平保持不变。这种编码的好处是能减少信号跳变次数但对接收端来说有一个隐患——如果连续传输大量逻辑1线上一直不跳变收发双方就难以维持时钟同步。为了解决这个问题USB协议规定了一个叫“位填充”的机制发送端在连续出现6个逻辑1之后强制插入一个逻辑0强制产生一次跳变让接收端能重新锁定时钟。接收端收到后会自动把插入的0删除掉。这些细节平时写应用层代码时看不到但一旦你调试到物理层故障比如信号完整性引起的同步丢失就需要回到这个层面去分析。2. 端点、管道与四种传输类型协议层的地基2.1 端点是什么端点是USB设备内部的一个数据存储单元你可以把它理解成设备里的“邮箱”。主机不能直接读写设备的内存或者寄存器它只能往端点上放数据、或者从端点上取数据。每个端点都有一个编号0到15同时区分方向IN方向是设备往主机发数据OUT方向是主机往设备写数据所以“端点3 IN”和“端点3 OUT”是两回事。其中端点0EP0是每个设备必须有的它是一个双向的控制端点专门用来完成设备枚举和控制类通信。设备刚插上时主机只认识端点0剩下的端点要等枚举完成后、主机了解了设备能力之后才会真正使用起来。这里有个很多初学者容易混淆的点端点编号和数据缓冲区大小不是随便定的端点描述符里必须明确说明端点的最大包长度、传输类型、轮询间隔这些参数主机是根据这些参数来调度总线时间的。2.2 管道是什么管道是主机与设备某个端点之间建立起来的逻辑通信通道它把“物理上的端点和方向”和“逻辑上的数据流”绑定起来。你可以把管道理解为“邮箱和邮递路线”的组合端点是邮箱本身管道则规定了数据从哪来、到哪去、以什么规则运输。USB协议里有两种管道流管道Stream Pipe和消息管道Message Pipe。流管道上的数据没有固定的结构边界比如批量传输的数据就是纯粹的字节流消息管道则要求数据必须遵循USB的请求/响应格式控制传输用的就是消息管道。理解这个概念对后面读协议文档很有帮助因为很多描述符字段和请求参数的设计都是围绕这两类管道的区别展开的。2.3 四种传输类型USB2.0把数据传输分成四种类型每一种都是针对不同的应用场景设计的搞清楚它们的取舍比背参数表和接口定义更有价值传输类型带宽保证错误重传典型场景控制传输有有枚举、设备配置、命令下发批量传输无有U盘读写、打印机数据传输中断传输有按轮询周期有鼠标、键盘、HID设备同步传输有无错误可容忍音频、视频实时流控制传输是最基础也最复杂的一种它的特点是先用SETUP阶段发送请求再用DATA阶段传数据最后用STATUS阶段确认结果整个过程是分阶段的。批量传输是为“可靠性优先、时效性靠后”的场合设计的它会在总线空闲时尽量占用带宽最大包长度在全速下是64字节、高速下是512字节。中断传输虽然名字里有“中断”但它并不是硬件中断而是设备保证在固定的时间间隔内被主机轮询一次所以叫“周期性轮询”更准确。同步传输则是唯一不做错误重传的因为它传的是音视频等实时数据重传反而会导致播放卡顿丢失一两个包是可以接受的。2.4 帧与微帧全速和低速模式下USB总线的时间被分成1ms一帧每帧开始时主机会发送一个SOFStart of Frame包用于同步和调度。高速模式下这一帧被进一步细分成8个125μs的微帧这样单位时间内的调度粒度更细能塞进更多交互。帧的概念对理解USB带宽估算很重要。以全速的同步音频设备为例每帧最多能传多少数据是有限制的因为一帧内除了数据包本身还有包间隔、握手包等开销。高速模式下的批量传输峰值速率也达不到线性482Mbps我记得很多实测都表明加上协议开销之后高速U盘的实际吞吐通常在30到40MB/s左右这还是在主控和存储都不拉胯的情况下。做带宽规划时不要拿480Mbps去算而是按实际量产测试的经验值去估。3. 拓扑与角色主机、设备、集线器怎么分工3.1 分层星型拓扑USB总线的拓扑结构是分层的星型结构核心是主机Host主机下面通过根集线器Root Hub引出端口每个端口可以接一个设备或者一个集线器集线器下面又可以再接设备和集线器最多支持7层拓扑、最多连接127个设备。主机在整个系统里是唯一的“总线管理者”所有的传输都由主机发起设备永远处于被动响应状态。这就是为什么两台上位机之间不能直接用USB线互连——没有主机和设备的分工总线事务就无从谈起。Android手机和电脑连起来手机默认是设备但很多手机开启了OTG功能之后角色会切换这就是OTG规范里做角色协商的结果核心还是建立“主机-设备”的关系。这个拓扑也意味着一个很常见的问题如果某个设备或者某条线缆出问题导致总线上出现持续性错误状态整条总线上的其他设备也会受到影响。所以集线器端口的过流保护和总线的错误恢复机制很重要不然一个劣质设备就能把一整个USB Hub拖垮。3.2 集线器的事务转换器集线器并不只是简单地把上游信号分发给下游端口它还承担着一个关键角色事务转换器Transaction Translator简称TT。为什么需要TT因为高速480Mbps和全速/低速12Mbps/1.5Mbps设备的通信机制差异较大全速和低速设备无法直接读懂高速总线上的事务需要通过集线器做一个“翻译”。具体来说当主机想和一个挂在高速集线器下面的全速设备通信时主机用高速事务把数据发给集线器集线器先缓存下来再以全速的时序转发给下游设备。这个过程对主机端是透明的但对带宽和延迟有影响。设计USB Hub时TT的设计决定了集线器同时处理多个低速设备时的并发能力早期有些集线器只有一个TT多个低速设备同时传输时会互相等待后来的多TT设计能让每个下行端口独立拥有一套转换资源这也是判断集线器芯片档次的指标之一。3.3 上拉电阻与速率识别主机怎么知道插入的设备是低速、全速还是高速答案是看D/D−上的电平状态。全速和高速设备在D线上接一个1.5kΩ的上拉电阻到3.3V低速设备则在D−线上接同样的上拉电阻。设备插入后主机在D或D−上检测到被拉高的电平就能判断出设备的存在和它的基础速率能力。这是比较经典的硬件细节。很多人在DIYUSB设备时容易遗漏这个上拉电阻结果设备插上后主机毫无反应。更麻烦的是有些MCU内部已经集成了这个上拉电阻而有些需要外部自行加上做原理图设计之前一定要查清楚芯片手册。高速设备的Chirp握手也是靠这套上拉机制来启动的主机检测到上拉后会先按全速模式给设备复位如果设备支持高速它会通过特定的K/J信号序列回应主机双方确认后一起切换到高速模式。4. 枚举流程设备连上后主机到底做了什么4.1 枚举的完整步骤枚举是USB设备最核心的启动流程很多“插上去没反应”的问题根源都在这里。我按实际发生顺序拆解如下设备插入VBUS上电设备内部上电复位D/D−上拉电阻生效。主机在端口上检测到电平变化知道有设备接入。主机向该端口发送复位信号SE0状态持续至少10ms设备收到复位后把地址重置为0。如果设备支持高速它会和主机完成Chirp握手链路切换到高速模式。主机向地址0发送GET_DESCRIPTOR请求读取设备描述符注意这里通常先只读前8字节确认端点的最大包长度后再完整读取18字节设备描述符。主机发送SET_ADDRESS请求给设备分配一个唯一地址1到127。主机用新地址继续读取配置描述符、接口描述符、端点描述符等全套信息。主机根据设备请求的电流和系统策略决定是否允许设备工作然后发送SET_CONFIGURATION请求激活某个配置。设备进入已配置状态可以正式开始业务通信。这个过程看起来简单但每步都有严格的超时和错误处理机制。比如第5步如果设备对GET_DESCRIPTOR毫无响应主机会重置端口并重试几次失败后直接标记端口错误。很多固件Bug就是在这里暴雷的——设备描述符里的最大包长度写错主机读取后续描述符时全部错位表现为设备在设备管理器里显示“无法识别的USB设备”。4.2 描述符体系设备如何“自我介绍”描述符是USB协议里最有特色的设计之一它是设备用来向主机描述自身能力的结构化数据块。标准描述符有设备描述符、配置描述符、接口描述符、端点描述符和字符串描述符它们之间是层级关系一个设备可以有多个配置一个配置可以有多个接口一个接口可以有多个端点。设备描述符里最重要的是bcdUSB协议版本号、idVendor厂商ID、idProduct产品ID和bMaxPacketSize0端点0最大包长度。厂商ID由USB-IF组织统一分配做量产产品必须申请个人DIY可以用私有ID。配置描述符里记载了电流需求 (bMaxPower) 和接口数量主机就是根据这个判断要不要给设备供更多电。接口描述符定义了一个功能单元比如一个复合设备像带麦克风的摄像头会有两个接口一个视频流接口加一个音频流接口。端点描述符则定义了每个端点的传输类型、方向、最大包长度和轮询间隔。这棵“描述符树”构成了USB设备的完整画像。调试的时候我习惯先把设备插上跑一次lsusb -v把整个描述符树完整导出来看一遍很多配置问题一眼就能发现比如端点地址冲突、描述符长度字段不对、字符串索引越界。4.3 标准请求枚举过程中主机向设备端点0发送的是一系列标准USB请求这些请求定义了固定的格式8字节的请求包包含bmRequestType、bRequest、wValue、wIndex和wLength几个字段。常见的标准请求有GET_DESCRIPTOR、SET_ADDRESS、SET_CONFIGURATION、GET_CONFIGURATION、GET_STATUS、CLEAR_FEATURE、SET_FEATURE、SET_INTERFACE、GET_INTERFACE等。这里有一个重要的概念请求类型字段bmRequestType里的bit6:5表示请求方向与接收方分别有“标准请求”“类请求”“厂商自定义请求”之分。标准请求是像HTTP里的标准方法一样所有设备必须实现的而类请求比如HID类的GET_REPORT是针对特定设备类的厂商自定义请求则完全由设备开发者自己定义常用于私有命令交互。调试时如果遇到设备没响应某个请求首先要确认这个请求是不是设备应该支持的标准请求很多固件只是把标准请求做了个空壳返回。5. 实战开发中的硬经验与常见坑5.1 怎么确认设备跑在哪个速率拿到一块开发板或者一个外设怎么最快速地确认当前USB链路的工作速率在Linux下lsusb能列出设备信息lsusb -t则能以树形结构显示总线和设备其中每个设备条目后面会有类似12M或480M的速率标注这就是当前链路协商出来的实际速率。Windows下可以用USB Tree Viewer这个工具它能显示设备挂在哪一层、当前速率是多少、端口状态等详细信息。有一类比较隐蔽的问题设备虽然支持高速但由于线缆质量差、连接器接触不良或者PCB走线阻抗不匹配主机和设备协商时可能降级到全速模式工作。这种情况最典型的表现是U盘读取速度从30MB/s暴跌到10MB/s以下而系统里不会有任何报错。所以排查速率异常时先别怀疑设备换一根短线、换一个直连主机背板的端口试一下往往就能定位问题。5.2 硬件设计上最容易翻车的几个点做过几个USB项目之后我总结出硬件设计上最常翻车的几个位置上拉电阻遗漏或取值错误。前面提到过1.5kΩ上拉到3.3V是速率识别的关键很多新手用1kΩ甚至10kΩ导致主机无法稳定识别插入事件。D/D−差分阻抗不控制。90Ω差分阻抗不是可选项是稳定跑高速的必要条件建议做阻抗计算并在打样时要求板厂管控。VBUS去耦和ESD防护缺失。VBUS上的电源纹波会直接影响收发器稳定性D/D−线上需要加ESD保护器件否则插拔瞬间的静电很容易打坏芯片接口。线缆损耗和长度超标。USB2.0规范建议高速模式下线缆长度不超过5米实际项目中超过3米就开始出现信号劣化非要长距离传输的话应该考虑用带延长器的有源线。5.3 调试USB通信的几种手段逻辑分析仪是最常用的USB调试手段但需要注意的是普通逻辑分析仪采样480Mbps的高速信号比较吃力建议选择带USB2.0协议解码的高采样率型号。低速和全速设备用几十块钱的逻辑分析仪就能解码出包内容到了高速就必须用真正的USB协议分析仪它能把SOF、令牌包、数据包、握手包完整抓出来还是那句老话硬件问题用示波器和分析仪固件问题用描述符导出和控制台日志。软件层面Linux下的usbmon和Wireshark配合可以抓取USB总线流量Windows下的USBPcap也有类似功能能抓到主机与设备之间的URB。这套组合免费且够用日常调试枚举失败、端点通信异常时能省下不少力气。抓包时重点看几个东西请求是否得到响应、返回的包长度与描述符声明的长度是否一致、端点是否返回STALL。我个人的经验是排查USB问题一定要分层次先确认物理连接和速率协商再用分析仪/抓包工具看协议层最后才回头检查固件逻辑。很多人一上来就盯着固件里的中断处理翻来覆去地看结果最后发现是PCB上D/D−顺序画反了这类教训真不少见。做USB开发这几年我最大的体会就是USB协议本身不难难的是在物理层和协议层之间来回定位问题而这一切的前提就是先把基本概念的地基夯实。后面这个系列我会接着往描述符编写、设备类协议、实际固件实现这些方向展开想深入的话可以先把这篇里的术语和流程消化掉特别是端点、传输类型和枚举这三块它们是后续所有内容的地基。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑