2. USB硬件拓扑结构:主机控制器(HCD)、根集线器(Root Hub)、USB设备、端点(Endpoint)的物理与逻辑层次
USB 总线采用树形拓扑结构,由主机控制器(Host Controller)作为根节点,通过根集线器(Root Hub)向下扩展,连接至各类 USB 设备。每个 USB 设备内部又包含多个端点(Endpoint),这些端点是 USB 通信的最小逻辑单元。理解这一物理与逻辑层次,是掌握 URB(USB Request Block)通信机制的基础。
2.1 物理拓扑层次概览
从物理连接角度看,USB 系统分为四个层级:
- 主机控制器(Host Controller):位于主机端,是 USB 总线的“大脑”,负责管理总线事务、调度传输、处理错误。
- 根集线器(Root Hub):集成在主机控制器内部或紧邻其旁,提供物理端口,负责检测设备连接/断开、供电管理、总线复位。
- USB 设备(USB Device):包括功能设备(如键盘、U盘)和外部集线器(Hub),通过端口接入总线。
- 端点(Endpoint):设备内部的通信接口,每个端点对应一个数据缓冲区,是 USB 传输的终点。
2.2 主机控制器(HCD)—— 总线的“大脑”
主机控制器驱动(Host Controller Driver, HCD)是 Linux USB 子系统的核心组件之一。它直接与硬件交互,负责:
- 总线调度:将 URB 转换为 USB 帧/微帧事务,按传输类型(控制、批量、中断、等时)分配带宽。
- 事务处理:生成 SOF(Start of Frame)包,发起 IN/OUT/SETUP 事务,处理握手包(ACK/NAK/STALL)。
- 错误恢复:检测总线错误(如 CRC 校验失败、超时),执行重试或报告错误状态。
- 电源管理:控制端口供电、挂起/唤醒状态。
| 规范 | 速度支持 | 传输方式 | Linux 驱动 |
|---|---|---|---|
| OHCI (Open HCI) | USB 1.1 (低速/全速) | 内存映射寄存器 | ohci-hcd |
| UHCI (Universal HCI) | USB 1.1 (低速/全速) | I/O 端口寄存器 | uhci-hcd |
| EHCI (Enhanced HCI) | USB 2.0 (高速) | 异步/周期列表调度 | ehci-hcd |
| xHCI (eXtensible HCI) | USB 3.x (超高速) | 事件环/命令环/传输环 | xhci-hcd |
struct usb_hcd 结构体抽象,每个主机控制器对应一个 usb_hcd 实例。驱动开发者通常不需要直接操作 HCD 寄存器,而是通过 USB 核心层提供的 API 提交 URB。
2.3 根集线器(Root Hub)—— 物理连接的起点
根集线器是主机控制器的一部分,在逻辑上被 USB 核心视为一个特殊的 USB 设备。它的主要职责包括:
- 端口管理:检测设备插入/拔出事件,通过端口状态寄存器报告给 HCD。
- 供电控制:为每个端口提供 5V 电源(最大 500mA/900mA,取决于 USB 版本)。
- 总线复位:当新设备连接时,对端口执行复位信号,使设备进入默认地址状态。
- 速度识别:通过 D+/D- 线路上的上拉电阻检测设备速度(低速/全速/高速/超高速)。
在 Linux 内核中,根集线器被枚举为一个 usb_device 实例,其 devnum 通常为 1。根集线器本身也包含一个默认的控制端点(端点 0),用于主机与根集线器之间的控制传输。
2.4 USB 设备 —— 功能与集线器
USB 设备分为两大类:
- 功能设备(Function Device):提供特定功能,如 HID(人机接口设备)、大容量存储、音频、视频等。
- 集线器设备(Hub Device):用于扩展端口数量,允许更多设备接入总线。集线器本身也是一个 USB 设备,拥有自己的端点。
每个 USB 设备在枚举过程中会被分配一个唯一地址(Address),范围 1~127。设备通过配置(Configuration)、接口(Interface)、端点(Endpoint)三级描述符向主机声明自身能力。
2.5 端点(Endpoint)—— 通信的最小逻辑单元
端点是 USB 设备中实际进行数据收发的逻辑实体。每个端点由端点号(Endpoint Number)和方向(Direction)唯一标识。端点 0 是每个设备必须包含的默认控制端点,用于设备枚举和控制传输。
2.5.1 端点类型
| 传输类型 | 端点类型 | 典型用途 | 带宽保证 | 错误重试 |
|---|---|---|---|---|
| 控制传输 | 控制端点 | 设备枚举、配置、命令 | 10% 保留带宽 | 硬件自动重试 |
| 批量传输 | 批量端点 | U盘、打印机、网络 | 无(空闲时传输) | 硬件自动重试 |
| 中断传输 | 中断端点 | 键盘、鼠标、游戏手柄 | 保证轮询间隔 | 硬件自动重试 |
| 等时传输 | 等时端点 | 音频、视频、摄像头 | 保证带宽 | 无重试 |
2.5.2 端点在 Linux 内核中的表示
在 Linux USB 子系统中,端点通过 struct usb_host_endpoint 结构体描述:
struct usb_host_endpoint {
struct usb_endpoint_descriptor desc; // 端点描述符(硬件信息)
struct list_head urb_list; // 挂载到此端点的 URB 链表
void *hcpriv; // 主机控制器私有数据
struct ep_device ep_dev; // 端点设备(sysfs 接口)
unsigned char *extra; // 额外描述符
int extralen;
int enabled; // 端点是否启用
};
关键字段说明:
desc:包含端点地址、方向、类型、最大包大小等硬件属性。urb_list:所有发往该端点的 URB 被挂载到此链表,由 HCD 调度处理。enabled:表示端点是否已启用。未启用的端点不会接收任何 URB。
pipe 宏(如 usb_rcvbulkpipe、usb_sndbulkpipe)指定端点和方向。
2.6 逻辑层次总结:从 URB 到物理信号
当 USB 设备驱动提交一个 URB 时,数据经历的完整路径如下:
- 设备驱动 构造 URB,指定目标端点、数据缓冲区、回调函数。
- USB 核心 将 URB 提交到对应
usb_host_endpoint的urb_list中。 - HCD 从
urb_list取出 URB,将其拆分为 USB 事务(Token + Data + Handshake)。 - 根集线器 将事务信号通过端口发送到 USB 总线。
- USB 设备 的端点硬件接收/发送数据,完成一次通信。
2.7 本章小结
USB 硬件拓扑结构是理解 URB 通信机制的前提。从主机控制器到端点,每一层都有明确的职责和抽象接口:
- 主机控制器(HCD):总线的调度中心,负责将 URB 转化为总线事务。
- 根集线器(Root Hub):物理连接的起点,管理端口状态和供电。
- USB 设备:通过配置、接口、端点三级描述符向主机声明能力。
- 端点(Endpoint):通信的最小逻辑单元,每种端点类型对应不同的传输特性和带宽策略。