3、USB传输模型:端点、管道、传输类型

好,咱们今天聊点实在的。USB传输模型,说白了就是数据怎么在主机和设备之间跑起来。很多初学者一上来就被各种术语搞晕了——端点、管道、控制传输、批量传输……其实没那么复杂。我当年刚接触USB时也绕了不少弯路,今天我把这些掰开揉碎了讲给你听。

3.1 端点——数据传输的“港口”

先说说端点。你可以把端点想象成设备上的一个数据港口。每个USB设备可以有多个端点,每个端点都有自己的编号和方向。

核心概念:端点就是USB设备内部的一个数据缓冲区,主机通过它来收发数据。每个端点用端点号+方向来唯一标识。

端点有几种类型?嗯,我习惯按方向分:

  • IN端点:设备→主机。设备往主机发数据。
  • OUT端点:主机→设备。主机往设备写数据。

注意,端点0比较特殊。它是每个USB设备必须有的控制端点,双向的,专门用来做枚举和控制传输。我在项目中遇到过有人把端点0当成普通数据端点用,结果枚举死活过不去——后来发现是描述符里端点0的配置写错了。

小提示:端点0不需要在配置描述符里声明,它是USB协议强制存在的。别画蛇添足。

3.2 管道——端点的“高速公路”

管道是什么?说白了,管道就是主机和设备端点之间的逻辑连接。你想想看,主机要跟端点通信,总得有条路吧?这条路就是管道。

管道有两个关键属性:

  • 关联的端点:管道一头连着主机,另一头连着设备的某个端点。
  • 传输类型:管道决定了数据怎么传——是控制、批量、中断还是同步。

我个人习惯把管道理解成“协议通道”。同一个端点,在不同时间可以通过不同管道传输不同数据。但实际设计中,一个端点通常只对应一种传输类型。

注意:管道是单向的,除了默认控制管道(端点0)是双向的。别想着用一个管道又收又发,除非你用端点0。

3.3 四种传输类型——各司其职

USB定义了四种传输类型。为什么是四种?因为不同的应用场景对数据的要求不一样。有的要可靠,有的要实时,有的要大量数据,有的要小数据量但频繁。

传输类型 特点 典型应用 我踩过的坑
控制传输 可靠、双向、数据量小 枚举、命令控制 描述符长度写错导致枚举失败
批量传输 可靠、单向、数据量大 U盘、打印机 缓冲区没对齐导致传输卡死
中断传输 可靠、低延迟、数据量小 鼠标、键盘 轮询间隔设太短浪费带宽
同步传输 不可靠、实时、数据量大 音频、视频 没做丢包处理导致音画不同步

3.3.1 控制传输——USB的“官道”

控制传输是USB协议的基础。每个USB设备都必须支持控制传输,因为枚举过程全靠它。控制传输分四个阶段:建立阶段、数据阶段(可选)、状态阶段。

我曾经调试一个设备,枚举到获取配置描述符时就卡住了。查了半天,发现是控制传输的数据阶段,我返回的描述符长度比主机请求的短,但状态阶段没正确处理——主机等不到状态包,直接超时了。

关键点:控制传输的状态阶段必须由设备返回一个零长度数据包(IN方向)或接收一个零长度数据包(OUT方向),表示传输完成。这个细节很容易被忽略。

3.3.2 批量传输——USB的“货车”

批量传输适合大数据量传输,比如U盘读写。它的特点是可靠,但延迟不确定——总线空闲时才传,总线忙就等着。

批量传输的端点需要配置最大包大小。全速下通常是64字节,高速下可以是512字节。我记得有次做U盘项目,批量传输总是丢数据,后来发现是端点最大包大小没对齐——主机那边要求512,我配了64,结果数据被截断了。

经验之谈:批量传输的缓冲区最好按最大包大小的整数倍对齐。否则容易出现“短包”问题,主机以为传输结束了,其实还有数据没发完。

3.3.3 中断传输——USB的“快递员”

中断传输名字带“中断”,但它不是硬件中断。它其实是主机定期轮询设备,看看有没有数据要传。适合鼠标、键盘这类需要低延迟但数据量小的设备。

中断传输有个关键参数——轮询间隔。全速设备最短1ms轮询一次,高速设备可以到125μs。我建议别把间隔设得太短,否则会浪费总线带宽。曾经有个项目,鼠标的轮询间隔设成了1ms,结果USB总线被占满了,其他设备都受影响。

避坑指南:中断传输的最大包大小有限制。全速下最大64字节,高速下最大1024字节。别想着用中断传大文件,那是批量传输的活。

3.3.4 同步传输——USB的“直播”

同步传输适合音频、视频这类实时数据。它的特点是保证带宽和延迟,但不保证数据正确——错了不重传。为什么?因为音频数据丢一帧还能忍,但重传导致的延迟更让人受不了。

同步传输没有握手阶段,数据丢了就丢了。我在做USB麦克风时遇到过一个问题:同步传输的数据包如果没对齐,音频会有爆音。后来发现是缓冲区大小没按帧周期计算好。

核心要点:同步传输的端点必须配置为同步端点,而且每个微帧只能传输一个数据包。高速下每125μs一个微帧,全速下每1ms一帧。

3.4 传输模型的关系图

说了这么多,咱们用一张图把关系理清楚。下面这张SVG图展示了主机、管道、端点、传输类型之间的整体关系。

USB传输模型关系图 USB传输模型关系图 USB主机 (软件栈 + 控制器) 管道(Pipe) 控制管道 | 批量管道 中断管道 | 同步管道 USB设备 (固件 + 端点) 端点(Endpoint) 端点0(控制) 端点1 IN(中断) 端点2 OUT(批量) 端点3 IN(同步) 四种传输类型 • 控制传输:可靠、双向、小数据量 → 枚举、命令 • 批量传输:可靠、单向、大数据量 → U盘、打印机 • 中断传输:可靠、低延迟、小数据量 → 鼠标、键盘 • 同步传输:不可靠、实时、大数据量 → 音频、视频 总结:主机通过管道与设备的端点通信,管道类型决定了传输方式 每个端点只能属于一种传输类型,端点0固定为控制传输

3.5 实际设计中的选择策略

好了,理论说完了,咱们聊聊实际中怎么选。我个人的经验是:

  1. 先看需求:数据量大不大?延迟要求高不高?要不要保证可靠性?
  2. 再定类型:大数据量+可靠→批量;小数据量+低延迟→中断;实时+可丢→同步;控制命令→控制。
  3. 最后配参数:最大包大小、轮询间隔、缓冲区对齐,一个都不能错。

实用建议:如果你不确定选哪种,先默认用控制传输做原型验证。等跑通了再根据性能需求换成其他类型。别一上来就追求最优方案,先跑起来再说。

嗯,这一章的内容就到这儿。端点、管道、传输类型这三个概念,是USB协议栈的基石。你把这些搞清楚了,后面讲枚举和状态机设计时就会轻松很多。记住一句话:端点是你设备上的港口,管道是主机到港口的航线,传输类型决定了这条航线上跑的是货轮、快艇还是邮轮。