1. USB中断传输概述

USB中断传输(Interrupt Transfer)是USB规范中定义的四种标准传输类型之一,专为需要周期性、低延迟、有限数据量的通信场景设计。在嵌入式Linux驱动开发中,中断端点是实现人机交互设备(HID)、游戏手柄、键盘、鼠标等实时输入设备的核心通信通道。

💡 核心认知: USB中断传输的“中断”并非硬件中断信号,而是指主机必须定期轮询设备以获取数据。这种轮询机制保证了确定性的最大延迟,是实时性优化的基础。

1.1 中断传输的定义与工作原理

USB中断传输是一种轮询驱动的单向或双向数据传输方式。主机控制器(Host Controller)为每个中断端点维护一个轮询间隔(bInterval),在每间隔到达时发起事务(Transaction)。

  • 轮询机制: 主机在每帧(Full/Low Speed)或微帧(High Speed)内检查中断端点是否有数据待传。
  • 数据方向: 通常为输入(IN)方向(设备→主机),也可支持输出(OUT)方向。
  • 事务组成: 每个中断事务包含令牌包(Token)、数据包(Data)、握手包(Handshake)三个阶段。
  • 错误重试: 支持硬件级自动重试,直到成功或超时。
📌 关键参数:bInterval
端点描述符中的bInterval字段定义了轮询间隔:
- Full/Low Speed:间隔 = bInterval × 1ms(范围1–255ms)
- High Speed:间隔 = 2^(bInterval-1) × 125μs(范围125μs–4.096ms)
USB中断传输事务时序图 USB中断传输事务时序(单次轮询) t 帧起始 下一帧 令牌包 数据包 握手包 📋 事务说明 • 令牌包:主机发送,包含端点地址和方向(IN/OUT) • 数据包:设备返回数据(最多bMaxPacketSize字节) • 握手包:主机确认接收(ACK/NAK/STALL)

1.2 中断传输的核心特点

特性 描述 对实时性的影响
周期性 主机按固定间隔轮询,保证最大延迟上限 延迟可预测,适合硬实时场景
低延迟 High Speed下最小间隔125μs,延迟极低 满足高刷新率输入设备需求
有限数据量 最大包大小受限(FS:64B, HS:1024B) 适合小数据块,避免总线占用
错误重试 硬件自动重试,保证数据完整性 增加确定性延迟,但保证不丢数据
带宽保证 USB规范保证中断传输占用不超过90%帧时间 避免被批量传输饿死
⚠️ 常见误区: 中断传输的“中断”二字容易让人误解为硬件中断驱动。实际上,USB中断传输完全依赖主机主动轮询,设备不能主动发起通信。这与PCIe/MSI等硬件中断有本质区别。

1.3 典型应用场景

1.3.1 HID设备(键盘、鼠标、触摸板)

HID(Human Interface Device)是中断传输最广泛的应用。键盘、鼠标等设备需要实时响应用户操作,数据量小(通常≤8字节),但对延迟敏感。

  • 键盘: 每次按键产生8字节报告(按键码+修饰键),轮询间隔通常8ms(125Hz)
  • 鼠标: 每次移动产生4-8字节报告(X/Y位移+按键),轮询间隔4ms(250Hz)
  • 触摸板: 多点触摸报告可达64字节,轮询间隔2ms(500Hz)

1.3.2 游戏手柄与摇杆

游戏外设对实时性要求极高,尤其是竞技类游戏。现代游戏手柄通常使用中断传输实现高轮询率。

  • Xbox/PlayStation手柄: 轮询间隔1ms(1000Hz),报告包含摇杆、扳机、按键状态
  • 飞行摇杆: 多轴模拟输入,报告大小16-32字节,轮询间隔2ms
  • 方向盘: 力反馈数据通过OUT中断下发,需要双向中断端点

1.3.3 其他实时应用

  • 工业传感器: 温度、压力等周期性数据采集,间隔10-100ms
  • 医疗设备: 心电监测、血糖仪等低数据率实时传输
  • 智能卡读卡器: 卡片插入检测和命令响应
USB中断传输应用场景架构 USB中断传输典型应用场景 USB主机控制器 HID设备 键盘 / 鼠标 / 触摸板 游戏外设 手柄 / 摇杆 / 方向盘 工业/医疗设备 传感器 / 监测仪 🔑 共同特征 • 数据量小(≤64字节/事务) • 延迟敏感(ms级) • 周期性轮询 • 即插即用 • 典型轮询率:125Hz(键盘) ~ 1000Hz(游戏手柄)

1.4 与批量/同步传输的区别

理解中断传输与其他传输类型的差异,是正确选择端点类型和优化实时性的前提。下表从多个维度进行对比:

对比维度 中断传输 批量传输 同步传输
传输特性 周期性轮询,保证延迟 尽力而为,无延迟保证 等时传输,固定带宽
延迟 可预测(ms级) 不可预测(可能被阻塞) 固定延迟(μs级)
数据完整性 硬件重试保证 硬件重试保证 无重试,可能丢数据
最大包大小 FS:64B, HS:1024B FS:64B, HS:512B FS:1023B, HS:1024B
带宽占用 ≤90%帧时间(保证) 剩余带宽(无保证) 预留带宽(固定)
典型应用 HID、游戏手柄、传感器 U盘、打印机、存储 音频、视频、摄像头
端点数量 最多16个IN + 16个OUT 最多16个IN + 16个OUT 最多3个IN + 3个OUT
错误处理 自动重试(3次) 自动重试(无限) 不重试,丢弃错误数据
🎯 选型建议:
- 需要保证数据完整性 + 低延迟 → 选择中断传输(HID、手柄)
- 需要高吞吐量 + 数据完整 → 选择批量传输(存储设备)
- 需要固定带宽 + 可容忍丢包 → 选择同步传输(音频流)

1.5 中断端点在USB描述符中的定义

在Linux内核中,中断端点通过端点描述符(Endpoint Descriptor)定义。以下是典型的端点描述符结构:

/* USB 2.0 规范中的端点描述符结构 */
struct usb_endpoint_descriptor {
    __u8  bLength;          /* 描述符长度:7字节 */
    __u8  bDescriptorType;  /* 描述符类型:0x05 */
    __u8  bEndpointAddress; /* 端点地址:bit7=方向(0:OUT,1:IN), bit3-0=端点号 */
    __u8  bmAttributes;     /* 传输类型:0x03=中断传输 */
    __le16 wMaxPacketSize;  /* 最大包大小(字节) */
    __u8  bInterval;        /* 轮询间隔(单位见规范) */
} __attribute__ ((packed));

/* 实际设备示例:USB键盘中断端点 */
static struct usb_endpoint_descriptor keyboard_intr_ep = {
    .bLength         = 7,
    .bDescriptorType = USB_DT_ENDPOINT,
    .bEndpointAddress = 0x81,  /* IN端点,端点号1 */
    .bmAttributes    = 0x03,   /* 中断传输 */
    .wMaxPacketSize  = cpu_to_le16(8),  /* 每次最多8字节 */
    .bInterval       = 8,      /* 轮询间隔8ms(125Hz) */
};
🔧 驱动开发提示: 在Linux USB驱动中,通过 usb_rcvintpipe(dev, endpoint) 和 usb_sndintpipe(dev, endpoint) 宏构造中断传输的URB管道。轮询间隔由硬件决定,驱动只能读取,不能修改。

1.6 本章小结

  • USB中断传输是一种轮询驱动的周期性传输,提供可预测的低延迟。
  • 核心参数bInterval决定了轮询频率,直接影响实时性。
  • 典型应用包括HID设备、游戏手柄、工业传感器等小数据量实时场景。
  • 与批量传输相比,中断传输有延迟保证;与同步传输相比,有数据完整性保证。
  • 在Linux驱动中,中断端点通过URB(USB Request Block)进行数据交互,驱动开发者需要理解端点描述符和轮询机制。