嵌入式Linux USB Host驱动移植与适配工程 - 第1节
1. USB协议基础
USB(Universal Serial Bus)采用星形-菊花链混合拓扑,由主机(Host)、集线器(Hub)和设备(Device)三级节点构成。整个总线以主机为根,通过集线器向下扩展,最多支持 127 个设备地址(含集线器自身)。
拓扑要点: 物理上为分层星形,逻辑上为分时共享总线。每一层集线器最多扩展 7 个端口,整个系统最多 7 层(含根集线器)。
1.2 主机与设备角色定义
USB 总线是严格的主从架构,所有事务均由主机发起,设备只能被动响应。角色定义如下:
| 角色 | 职责 | 典型硬件 | 软件栈 |
|---|---|---|---|
| 主机 (Host) | 调度总线、管理枚举、分配带宽、发起传输 | OHCI/EHCI/xHCI 控制器 | USB Core → HCD → 控制器驱动 |
| 设备 (Device) | 响应主机请求、报告描述符、传输数据 | U盘、鼠标、摄像头、网卡 | 固件 → 设备端逻辑 |
| 集线器 (Hub) | 端口扩展、状态检测、电源管理 | 独立 Hub 芯片或集成在 SoC | Hub 驱动 (usb-hub) |
嵌入式要点: 在嵌入式 Linux 中,主机角色通常由 SoC 内置 USB OTG 控制器工作在 Host-only 模式实现。驱动移植的核心是让 HCD(Host Controller Driver)正确绑定硬件寄存器。
1.3 USB传输类型
USB 规范定义了 4 种传输类型,分别对应不同的带宽、延迟和可靠性需求。驱动开发者必须根据设备端点描述符中的 bmAttributes 字段选择正确的传输类型。
1.3.1 传输类型对比
| 传输类型 | 端点类型 | 带宽 | 延迟 | 纠错 | 典型设备 |
|---|---|---|---|---|---|
| 控制传输 | Control | 低 (10% 保留) | 中等 | 硬件重试 + CRC | 枚举过程、配置命令 |
| 批量传输 | Bulk | 高 (尽力而为) | 不保证 | 硬件重试 + CRC | U盘、打印机 |
| 中断传输 | Interrupt | 低 (保证轮询) | 低 (1~255ms) | 硬件重试 + CRC | 鼠标、键盘 |
| 同步传输 | Isochronous | 高 (预留) | 极低 (固定) | 无重试 (可 CRC) | 摄像头、音频 |
1.3.2 各传输类型详解
- 控制传输 (Control Transfer):USB 协议的基石,所有设备必须支持端点 0。分为 Setup、Data(可选)、Status 三个阶段。用于设备枚举、获取描述符、设置配置。
- 批量传输 (Bulk Transfer):利用空闲带宽传输大量数据,不保证延迟。在 USB 2.0 下理论速度可达 53.248 MB/s。驱动中通常使用 URB(USB Request Block)提交批量请求。
- 中断传输 (Interrupt Transfer):主机以固定间隔轮询设备,保证最大延迟。轮询间隔在端点描述符的
bInterval字段中指定。适用于人机交互设备。 - 同步传输 (Isochronous Transfer):预留固定带宽,无重传机制,允许少量数据错误。用于实时音视频流。驱动中需注意缓冲区管理和帧同步。
1.4 端点与管道模型
USB 通信的底层抽象是端点(Endpoint)和管道(Pipe):
- 端点:设备上的数据收发单元,每个端点有唯一地址(Endpoint Number)和方向(IN/OUT)。端点 0 为控制端点,所有设备必须支持。
- 管道:主机与端点之间的逻辑连接。管道在设备枚举时建立,由
usb_host_endpoint结构体描述。
驱动映射: Linux 内核中,每个 URB 提交时需指定
pipe 宏(如 usb_rcvbulkpipe、usb_sndctrlpipe),该宏将端点号、方向、传输类型编码为 32 位整数,HCD 据此调度事务。
1.5 枚举过程简述
设备插入后,主机通过以下步骤完成枚举,这是驱动移植中必须验证的基础流程:
- 复位:主机向设备发送复位信号,设备地址恢复为 0。
- 获取设备描述符:主机通过控制传输读取前 8 字节(含
bMaxPacketSize0)。 - 再次复位:根据
bMaxPacketSize0重新配置端点 0 最大包长。 - 设置地址:主机分配唯一地址(1~127),设备确认后切换地址。
- 获取完整描述符:读取设备描述符、配置描述符、接口描述符、端点描述符。
- 选择配置:主机发送
Set Configuration请求,设备进入配置状态。
移植陷阱: 在嵌入式平台上,如果根集线器驱动未正确实现端口状态检测,设备插入后可能无法触发复位信号,导致枚举卡在第一步。此时应检查 HCD 的
hub_control 回调中 GetPortStatus 和 SetPortFeature 的实现。
1.6 本章小结
| 知识点 | 核心要点 | 驱动关联 |
|---|---|---|
| 总线拓扑 | 星形-菊花链混合,最多7层127设备 | Hub 驱动负责端口管理 |
| 主机角色 | 唯一总线主控,发起所有事务 | HCD 实现调度器 |
| 控制传输 | 双向、可靠、用于枚举和配置 | 端点0,URB 类型 PIPE_CONTROL |
| 批量传输 | 大块数据、尽力而为、硬件重试 | Bulk 端点,URB 类型 PIPE_BULK |
| 中断传输 | 低延迟、固定轮询、人机交互 | Interrupt 端点,URB 类型 PIPE_INTERRUPT |
| 同步传输 | 固定带宽、无重传、实时流 | Isochronous 端点,URB 类型 PIPE_ISOCHRONOUS |