1. USB系统概述
1.1 USB总线拓扑结构
USB(Universal Serial Bus)采用树形分层星型拓扑,由一个主机控制器(Host Controller)作为根节点,通过集线器(Hub)向下扩展,最多支持7层设备级联(含根集线器)。每个物理连接点称为端口(Port),主机与设备之间始终是主从关系:主机发起所有事务,设备只能被动响应。
关键约束:USB 2.0 规范规定,任意设备到主机的路径上最多经过 5 个非根集线器,总电缆长度不超过 5 米(低速/全速)或 5 米(高速需考虑信号衰减)。
调试要点:在枚举阶段,主机通过端口状态变化(Port Change)检测设备插入。逻辑分析仪抓取 D+/D- 信号时,应重点关注 SE0(Single-Ended Zero)、J/K 状态以及帧起始包(SOF)的出现。
1.2 主机控制器与设备角色
| 角色 | 功能描述 | 典型硬件/软件 | 调试关注点 |
|---|---|---|---|
| 主机控制器 | 管理总线事务,生成帧起始包(SOF),处理传输错误 | EHCI(USB 2.0 HS)、xHCI(USB 3.x) | 寄存器状态、中断触发、调度表 |
| 根集线器 | 提供物理端口,检测设备连接/断开,复位端口 | 集成在主机控制器内部 | 端口状态寄存器、复位时序 |
| 集线器 | 扩展端口,转发事务,处理速度转换(TT) | USB 2.0 Hub、USB 3.0 Hub | TT(事务转换器)配置、级联深度 |
| 功能设备 | 实现具体功能(存储、HID、音频等) | U盘、鼠标、键盘、摄像头 | 端点描述符、配置选择 |
常见调试陷阱:在 USB 2.0 高速模式下,主机控制器通过Chirp K/J 握手协商设备速度。如果逻辑分析仪只看到 Chirp K 而没有后续 Chirp J,说明设备不支持高速,主机将回退到全速模式。此时应检查 D+ 上拉电阻(1.5kΩ)是否正常。
1.3 USB协议栈分层架构
USB 协议栈采用分层设计,从物理信号到应用数据共分为4层。每一层对上层屏蔽实现细节,下层提供标准化服务接口。
- 物理层(Physical Layer):定义电气特性、信号编码(NRZI)、位填充、差分信号(D+/D-)。
- 数据链路层(Data Link Layer):封装为包(Packet)结构,包括 SOP、PID、数据域、CRC。主机控制器负责包传输与错误重试。
- 协议层(Protocol Layer):组织为事务(Transaction),包含令牌包、数据包、握手包。控制传输、批量传输、中断传输、等时传输在此层实现。
- 应用层(Application Layer):通过端点(Endpoint)和管道(Pipe)与设备功能通信。设备框架(如 HID、Mass Storage)在此层定义。
1.4 Linux USB子系统软件架构
在 Linux 内核中,USB 子系统遵循分层驱动模型,从上到下依次为:
- USB 核心层 (USB Core):提供设备枚举、配置管理、urb(USB Request Block)分配与提交、标准请求处理。位于
drivers/usb/core/。 - 主机控制器驱动 (HCD):抽象不同硬件(EHCI、OHCI、UHCI、xHCI),实现
struct hc_driver接口。位于drivers/usb/host/。 - 设备驱动层:针对具体设备类(HID、存储、网络)实现
struct usb_driver,通过probe()回调绑定设备。
枚举流程中的关键数据结构:
// USB设备结构体 (drivers/usb/core/usb.h)
struct usb_device {
int devnum; // 设备地址 (1-127)
enum usb_device_state state; // 设备状态机
enum usb_device_speed speed; // 速度枚举
struct usb_device_descriptor descriptor; // 设备描述符
struct usb_host_config *config; // 当前配置
struct usb_device *parent; // 父集线器
struct usb_bus *bus; // 所属总线
};
// USB请求块 (include/linux/usb.h)
struct urb {
struct list_head urb_list; // 链表节点
struct usb_device *dev; // 目标设备
unsigned int pipe; // 管道 (端点+方向)
int status; // 传输状态
unsigned int transfer_flags; // 传输标志
void *transfer_buffer; // 数据缓冲区
dma_addr_t transfer_dma; // DMA地址
int actual_length; // 实际传输长度
int error_count; // 错误计数
};
1.5 速度识别与信号状态
USB 2.0 通过 D+/D- 上的上拉电阻位置识别设备速度:
| 速度模式 | 上拉电阻位置 | 信号速率 | 空闲状态 | 典型应用 |
|---|---|---|---|---|
| 低速 (LS) | D- 上拉 | 1.5 Mbps | D- = 高, D+ = 低 | 鼠标、键盘 |
| 全速 (FS) | D+ 上拉 | 12 Mbps | D+ = 高, D- = 低 | 音频、HID |
| 高速 (HS) | D+ 上拉 + Chirp 握手 | 480 Mbps | D+ = 高, D- = 低 | 存储、视频 |
信号分析技巧:使用逻辑分析仪抓取枚举过程时,建议同时捕获 D+ 和 D- 两路信号。观察复位信号(SE0)持续时间(至少 10ms),以及设备在复位结束后是否立即拉高对应数据线。高速设备会在复位后发出 Chirp K(D+ 驱动为低,D- 驱动为高),主机以 Chirp J/K 交替响应。
1.6 本章小结
USB 系统的树形拓扑、主从角色和分层协议栈是理解枚举流程的基础。在后续章节中,我们将深入分析每个枚举步骤的信号波形、Linux 内核代码路径以及硬件调试方法。掌握本章内容后,你将能够:
- 识别 USB 总线拓扑中的设备层级关系
- 区分主机控制器、集线器、功能设备在枚举中的职责
- 理解协议栈各层在枚举过程中的数据封装与传递
- 通过 D+/D- 信号状态初步判断设备速度与连接状态