1. USB协议基础回顾

在深入 QNX USB 驱动开发之前,必须牢固掌握 USB 协议的核心概念。本章节将系统回顾 USB 2.0 与 USB 3.0 的拓扑结构、主机与设备的角色定义,以及四种传输类型(控制、批量、中断、同步)的特性与适用场景。这些知识是后续配置端点与排查批量传输故障的基石。

1.1 USB 2.0 / 3.0 拓扑结构

USB 总线采用星形-层级拓扑结构,由主机(Host)、集线器(Hub)和设备(Device)组成。主机位于拓扑的根节点,集线器用于扩展端口,设备是功能端点。

关键差异: USB 2.0 采用半双工广播总线,所有设备共享 480 Mbps 带宽;USB 3.0 引入全双工独立通道,数据传输速率提升至 5 Gbps(SuperSpeed),且物理层与电气特性完全不同。
USB 2.0 vs USB 3.0 拓扑结构对比 USB 2.0 (半双工) 主机 (Host) 集线器 (Hub) 设备 1 设备 2 设备 3 USB 3.0 (全双工) 主机 (Host) 集线器 (Hub) 设备 A 设备 B 设备 C USB 2.0 共享带宽,设备间需仲裁;USB 3.0 每设备独立双向通道,支持同时收发

1.2 主机与设备角色

USB 通信采用主从模型,主机始终控制总线上的所有事务,设备不能主动发起通信。

角色 职责 典型实现
主机(Host) 调度总线事务、管理带宽、枚举设备、发送请求 PC、嵌入式 SoC(如 i.MX8、R-Car)
设备(Device) 响应主机请求、报告状态、传输数据 U 盘、摄像头、传感器、打印机
集线器(Hub) 端口扩展、信号中继、连接/断开检测 独立 Hub 芯片、主板内置 Hub
QNX 开发提示: 在 QNX 中,USB 主机控制器驱动(HCD)负责管理硬件寄存器,而 USB 协议栈(io-usb)负责枚举和事务调度。编写 BSP 时,需要确保 HCD 正确初始化并注册到 io-usb。

1.3 传输类型概述

USB 定义了四种传输类型,每种类型对应不同的端点属性(传输方向、数据速率、可靠性要求)。端点在设备配置阶段通过端点描述符(Endpoint Descriptor)声明其传输类型。

USB 四种传输类型特性对比 控制传输 Control Transfer 双向、可靠、枚举用 端点 0 固定使用 批量传输 Bulk Transfer 非实时、大数据量 U盘、打印机 中断传输 Interrupt Transfer 低延迟、轮询 HID 键盘/鼠标 同步传输 Isochronous Transfer 实时、无重传 音频/视频流 传输类型选择原则 控制:设备配置与命令;批量:大数据块,保证正确性;中断:周期性小数据;同步:实时流,容忍丢包 USB 2.0 批量传输最大包 512 字节;USB 3.0 批量传输最大包 1024 字节,支持 Streams 协议

1.4 传输类型详细对比

特性 控制传输 批量传输 中断传输 同步传输
方向 双向(Setup/Data/Status) 单向(IN 或 OUT) 单向(IN 或 OUT) 单向(IN 或 OUT)
可靠性 高(硬件重试 + 握手) 高(硬件重试 + 握手) 高(硬件重试 + 握手) 低(无重传,无握手)
带宽保证 无(尽力而为) 无(仅用剩余带宽) 有(轮询间隔保证) 有(预留固定带宽)
典型应用 枚举、设置配置、类命令 U 盘读写、打印机数据 键盘、鼠标、游戏手柄 USB 摄像头、音频设备
USB 2.0 最大包 64 字节 512 字节 64 字节(FS)
1024 字节(HS)
1023 字节(FS)
1024 字节(HS)
USB 3.0 最大包 512 字节 1024 字节 1024 字节 1024 字节

1.5 批量传输与故障排查关联

在 QNX USB 驱动开发中,批量传输是最常出问题的传输类型,原因包括:

  • 端点配置错误: 端点描述符中的 wMaxPacketSize、bInterval 等字段设置不正确,导致主机拒绝配置。
  • 缓冲区对齐问题: QNX 的 USB 栈要求 DMA 缓冲区满足特定对齐(通常为 32 字节或 cache line 对齐),否则传输失败。
  • 带宽竞争: 批量传输使用剩余带宽,当总线上存在多个高速中断或同步传输时,批量传输可能被无限延迟。
  • Streams 协议(USB 3.0): 批量端点支持 Streams 时,驱动程序必须正确管理 Stream ID,否则导致数据错乱。
实战警告: 在 QNX 中,批量传输的故障通常表现为 io-usb 日志中的 USB_ERR_TIMEOUT 或 USB_ERR_STALLED。排查时,首先检查端点描述符的配置是否与硬件数据手册一致,其次确认 DMA 缓冲区是否在非缓存(non-cached)内存区域。