🔥作者简介: 一个平凡而乐于分享的小比特,中南民族大学通信工程专业研究生,研究方向无线联邦学习
🎬擅长领域:驱动开发,嵌入式软件开发,BSP开发
❄️作者主页:一个平凡而乐于分享的小比特的个人主页
✨收录专栏:通信协议,本专栏为记录项目中用到的知识点,以及一些硬件常识总结
欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖

USB HID通信协议详解
一、什么是USB HID?
USB HID(Human Interface Device,人机接口设备)是USB协议中的一个标准设备类别,专门为需要与人交互的设备设计。
生活中的HID设备举例:
- 🖱️ 鼠标 - 移动光标、点击操作
- ⌨️ 键盘 - 输入文字、快捷键
- 🎮 游戏手柄 - 控制游戏角色
- 📱 触摸屏 - 手指触控输入
- ✏️ 绘图板 - 专业绘图输入
二、HID的核心特点
对比表格:HID vs 其他USB设备类型
| 特性 | USB HID设备 | 其他USB设备(如存储设备) |
|---|---|---|
| 主要用途 | 人机交互 | 数据传输、存储 |
| 通信方式 | 中断传输为主 | 批量传输为主 |
| 延迟要求 | 低延迟(实时响应) | 可接受一定延迟 |
| 数据量 | 小数据包(通常<64字节) | 大数据量(MB/GB级别) |
| 即插即用 | 无需额外驱动(系统自带) | 可能需要专用驱动 |
| 功耗 | 通常较低 | 可能较高 |
三、HID通信模型图解
┌─────────────────────────────────────────────────┐
│ 应用程序层 │
├─────────────────────────────────────────────────┤
│ 操作系统HID驱动程序 │
├─────────────────────────────────────────────────┤
│ USB协议栈(主机端) │
├─────────────────────────────────────────────────┤
│ USB物理连接 │
├─────────────────────────────────────────────────┤
│ USB协议栈(设备端) │
├─────────────────────────────────────────────────┤
│ HID固件(设备固件层) │
├─────────────────────────────────────────────────┤
│ 物理输入(按键、移动、触摸等) │
└─────────────────────────────────────────────────┘
四、HID描述符详解
HID描述符层次结构:
设备描述符 → 配置描述符 → 接口描述符 → HID描述符 → 端点描述符 → 报告描述符
关键描述符说明:
1. HID描述符 - 告诉主机这是一个HID设备
struct hid_descriptor {
uint8_t bLength; // 描述符长度
uint8_t bDescriptorType; // 描述符类型(HID)
uint16_t bcdHID; // HID规范版本
uint8_t bCountryCode; // 国家/地区代码
uint8_t bNumDescriptors; // 下级描述符数量
uint8_t bDescriptorType2; // 报告描述符类型
uint16_t wDescriptorLength; // 报告描述符长度
};
2. 报告描述符 - HID的"灵魂",定义设备能力
用途:告诉主机"我能做什么"
内容:定义按钮、轴、滑块等输入元素
格式:基于项目的紧凑二进制格式
五、报告描述符实例分析
简单鼠标的报告描述符示例:
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x02, // Usage (Mouse)
0xA1, 0x01, // Collection (Application)
0x09, 0x01, // Usage (Pointer)
0xA1, 0x00, // Collection (Physical)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (1)
0x29, 0x03, // Usage Maximum (3)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x95, 0x03, // Report Count (3 buttons)
0x75, 0x01, // Report Size (1 bit per button)
0x81, 0x02, // Input (Data,Var,Abs)
0x95, 0x01, // Report Count (1)
0x75, 0x05, // Report Size (5 bits padding)
0x81, 0x01, // Input (Cnst,Arr,Abs)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x30, // Usage (X)
0x09, 0x31, // Usage (Y)
0x15, 0x81, // Logical Minimum (-127)
0x25, 0x7F, // Logical Maximum (127)
0x75, 0x08, // Report Size (8 bits)
0x95, 0x02, // Report Count (2)
0x81, 0x06, // Input (Data,Var,Rel)
0xC0, // End Collection
0xC0 // End Collection
报告描述符可视化:
鼠标报告格式(共3字节):
字节0: [按钮3][按钮2][按钮1][0][0][0][0][0]
字节1: X轴移动量(-127到127)
字节2: Y轴移动量(-127到127)
六、HID通信流程
典型交互场景:用户移动鼠标
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ 用户 │───▶│ 鼠标 │───▶│ USB总线 │───▶│ 主机 │
│ 移动鼠标 │ │ 传感器 │ │ │ │ 操作系统 │
└─────────┘ └─────────┘ └─────────┘ └─────────┘
│ │ │ │
│ │ │ │
▼ ▼ ▼ ▼
1.检测移动 2.生成报告 3.传输数据 4.解析报告
(X=-10, (3字节数据) (中断传输) (更新光标
Y=+5) 位置)
通信时序图:
text
设备(鼠标) 主机
│ │
│ 定期轮询(如8ms一次) │
│◀───────────────────────│
│ │
│ 有数据:发送报告 │
│───────────────────────▶│
│ 无数据:返回NAK │
│───────┐ │
│ │ │
│ 等待下次轮询 │
│◀──────┘ │
七、HID传输类型对比
| 传输类型 | 使用场景 | 特点 | 数据量 | 实时性 |
|---|---|---|---|---|
| 中断传输 | 键盘按键、鼠标移动 | 保证最大延迟时间 | 小(1-64字节) | 高 |
| 控制传输 | 获取描述符、配置设备 | 可靠、有错误检测 | 小到中 | 中等 |
| 批量传输 | HID打印机、扫描仪 | 大数据量、无延迟保证 | 大 | 低 |
八、实际应用场景
场景1:游戏手柄设计
报告描述符需要定义:
- 12个按钮(每个1位)
- 2个模拟摇杆(每个16位,X/Y轴)
- 1个方向键(4位)
- 2个扳机键(每个8位)
总报告大小:约8字节
场景2:带多媒体功能的键盘
扩展报告描述符支持:
- 标准键码(字母、数字)
- 多媒体键(播放、暂停、音量)
- LED状态(Caps Lock、Num Lock)
- 消费者控制页面功能
九、HID开发要点
1. 设计报告描述符时:
- 优先使用标准用法页(Usage Page)
- 合理组织集合(Collections)
- 优化报告大小(减少不必要的数据)
2. 固件开发注意事项:
- 正确处理SETUP事务
- 及时响应GET_REPORT请求
- 确保报告数据的实时性
3. 主机端开发:
- 使用操作系统提供的HID API
- 正确处理设备热插拔
- 考虑多设备同时使用的情况
十、HID协议的优势与局限
✅ 优势:
- 即插即用 - 操作系统内置驱动
- 低延迟 - 适合实时交互
- 标准化 - 跨平台兼容性好
- 灵活 - 可通过报告描述符自定义功能
⚠️ 局限:
- 数据量有限 - 不适合大数据传输
- 描述符复杂 - 学习曲线较陡
- 带宽受限 - 高速设备可能需要其他方案
总结
USB HID协议是人机交互设备的基石,它通过标准化的描述符 和高效的传输机制 ,让各种输入设备能够即插即用。理解HID的关键在于掌握报告描述符 的设计和中断传输的特性。无论是简单的键盘鼠标,还是复杂的游戏外设,都是基于这一套灵活而强大的协议实现的。
随着技术的发展,HID over USB-C、无线HID等扩展也在不断演进,但核心的HID协议概念始终保持一致,这充分体现了其设计的优雅和前瞻性。