USB系统架构:Host、Device、Hub的角色与拓扑结构
做USB开发这么多年,我见过不少工程师一上来就撸代码,结果被枚举流程搞得晕头转向。说白了,很多人没搞明白USB系统到底是怎么搭起来的。今天咱们就把这张图先画清楚——Host、Device、Hub,这三个角色各司其职,拓扑结构也不是你想的那样随便接。
一、USB的拓扑长什么样?
USB采用星形分层拓扑,不是总线型,也不是环形。只有一个Host,下面可以挂Hub,Hub再往下挂Device或更多的Hub。层数最多7层(包括根Hub那一层)。
我刚开始做USB时,以为可以像I2C那样随便挂一堆设备。结果有一次项目里,我在第5层Hub下面又串了一个Hub,设备死活枚举不过去。查了半天规格书才发现——层数超了。
核心约束: 一个USB系统中,Host有且只有一个。Hub最多级联5层(不算根Hub)。总设备数(含Hub)不超过127个。
下面这张图,是我每次培训必画的拓扑结构。你一看就明白:
二、三个角色的分工
1. Host(主机)—— 整个系统的老大
Host是USB系统中唯一能发起事务的节点。所有的数据传输,都由Host主动发起。Device只能被动响应。我见过有人问「Device能不能主动给Host发数据?」——不行,想都别想。
Host内部一般包含三部分:
- USB主机控制器(Host Controller):硬件层面,负责处理总线上的信号和事务。常见的有EHCI(USB 2.0高速)、xHCI(USB 3.x)。
- 主机软件栈(Host Software Stack):驱动层,管理枚举、带宽分配、电源管理等。
- 根Hub(Root Hub):集成在Host内部,提供物理端口。一般PC主板上那两三个USB口,就是根Hub的端口。
我个人的习惯: 调试枚举问题时,先确认根Hub是否正常工作。用逻辑分析仪抓D+/D-上的信号,看有没有SE0、J/K状态跳变。根Hub没动静,后面全白搭。
2. Device(设备)—— 听话的执行者
Device不能主动说话,只能等Host来问。每个Device都有一个唯一的地址(1~127),由Host在枚举时分配。
Device内部逻辑相对简单:
- 接收Host发来的令牌包(Token Packet)
- 根据令牌类型,准备数据包(Data Packet)或接收数据
- 返回握手包(Handshake Packet)确认状态
Device有四种传输类型,我列个表方便你对比:
| 传输类型 | 典型设备 | 特点 | 带宽保证 |
|---|---|---|---|
| 控制传输 | 所有设备(枚举阶段) | 双向、可靠、数据量小 | 有(10%~20%) |
| 批量传输 | U盘、打印机 | 可靠、数据量大、无实时性 | 无(空闲时才能发) |
| 中断传输 | 鼠标、键盘 | 可靠、数据量小、周期性轮询 | 有(按轮询间隔) |
| 同步传输 | 摄像头、音频 | 不可靠(无重传)、实时性高 | 有(固定带宽) |
嗯,这里要注意:控制传输是所有设备必须支持的。枚举阶段用的就是控制传输。你写固件时,端点0(默认控制端点)必须实现,否则Host连你是谁都不知道。
3. Hub(集线器)—— 默默无闻的中转站
Hub的作用就是扩展端口。它自己不处理数据内容,只负责信号中继、电源管理和设备连接检测。
Hub的核心功能:
- 信号中继:把上游Host发来的信号整形、放大后转发到下游端口。
- 设备检测:每个下游端口都有D+/D-上的上拉/下拉电阻检测电路。设备插入/拔出时,Hub能检测到电平变化,并通知Host。
- 电源管理:每个端口可以单独控制电源开关。Host通过Hub类请求(SetPortFeature/PORT_POWER)来控制。
- 速度协商:Hub能识别设备是全速、高速还是低速,并做相应的事务分割(Transaction Translator, TT)。
我曾经踩过的坑: 有一次用了一个廉价Hub,它的TT实现有问题。高速Host往全速设备发数据时,TT把数据包分割错了,导致设备一直NAK。后来换了带独立TT的Hub芯片才解决。所以选Hub芯片时,一定要看它的TT是每个端口独立还是所有端口共享。共享TT在高负载下容易丢包。
三、拓扑结构背后的设计逻辑
你可能会问:为什么USB非要搞成这种星形分层结构?直接像I2C那样挂一条总线不行吗?
我分析下来,主要有三个原因:
- 信号完整性:USB是高速差分信号(USB 2.0高速480Mbps,USB 3.0高达5Gbps)。如果搞成总线型,分支反射、信号衰减根本控制不住。星形拓扑每个分支都是点对点,信号质量好得多。
- 热插拔支持:每个端口独立检测,插拔一个设备不影响其他设备。总线型拓扑里,一个设备短路可能拉死整条总线。
- 带宽管理:Host可以精确控制每个端口的带宽分配。Hub只是透明转发,不参与调度。这样Host对整个总线的流量一目了然。
一句话总结: USB的拓扑结构,本质上是「一个Host集中管控,Hub做物理扩展,Device被动响应」的分层模型。理解了这个模型,你才能明白为什么枚举流程是那样设计的——Host必须一层一层地把Hub和Device「认」出来。
四、实际项目中的拓扑考量
做产品设计时,拓扑结构直接影响你的硬件方案和固件复杂度。我列几个实际中要注意的点:
- 层数限制:如果你的设备需要级联多个Hub(比如工业现场的数据采集系统),一定要算清楚层数。超过7层,Host根本不会去枚举后面的设备。
- 电源预算:每个Hub端口最多提供500mA(USB 2.0)或900mA(USB 3.0)。如果下游设备功耗大,需要用自供电Hub或者加外部电源。我见过一个项目,5个摄像头挂在一个总线供电Hub上,结果电压被拉低到4.2V,摄像头轮流掉线。
- 带宽分配:所有设备共享同一个Host的带宽。USB 2.0高速理论带宽480Mbps,但实际有效数据吞吐量也就40~45MB/s。如果挂多个U盘同时读写,性能会急剧下降。
- Hub的TT性能:高速Host接全速/低速设备时,数据要经过Hub的TT做速度转换。TT性能差的Hub,全速设备的数据延迟会很大。鼠标键盘还好,但如果是全速的HID游戏手柄,延迟高了体验很差。