USB HID Usage Tables 1.3 详解:从键盘到街机的即插即用底层约定
简介《USB HID Usage Tables 1.3》是USB Implementers Forum于2022年1月发布的HID使用表规范文档面向USB设备开发者、硬件工程师、驱动程序员与系统集成商用于解决HID设备功能元素标准化定义与跨平台互操作问题。资源包共1个PDF文件约4.09MB内容涵盖Usage ID分类、Usage Page上下文、Report Descriptor结构、设备类定义、协议传输及向后兼容性等核心章节并附有Microsoft、Intel、Google、Apple、Logitech等公司专家参与的贡献者列表与完整修订历史。文档详细定义了键盘按键、鼠标按钮、游戏控制器、触摸屏等设备的Usage ID可帮助读者准确理解HID报告描述符的编写逻辑掌握新版本引入的Usage扩展与修正内容为设备固件开发、驱动调试及标准符合性验证提供权威依据。目前已有560人学习下载适合需要查阅官方规范原文的中高级开发者参考使用。1. 到底什么是 USB HID Usage Tables从一个“插上就能用”的困惑说起你有没有想过一个问题为什么随便买一个键盘插到电脑上不管它是几十块的薄膜键盘还是上千块的机械键盘电脑都能立刻认出“这是键盘”而且按下 A 键屏幕上就出 A鼠标也一样换一个牌子、换一种造型插上就能动。这背后其实藏着一份“公共词典”它的名字叫 USB HID Usage Tables最新版本是 1.3。通俗地说这份文档就是 USB 人机交互设备HID世界的“翻译对照表”。它规定了键盘上每一个按键、鼠标上每一个按钮、手柄上每一根摇杆分别用哪个数字编号来表示。操作系统拿到这些编号就知道你按的是“回车”还是“退格”。没有这份表每个厂商各编各的号电脑就彻底懵了。所以它值得搞懂因为它是所有输入设备能“即插即用”的底层约定。2. 为什么需要一份“公共词典”HID 设备背后的编号难题2.1 没有标准编号操作系统就得给每个设备写一套驱动想象一下如果每家键盘厂商都自己定义“回车键 37 号”“退格键 91 号”那操作系统每遇到一个新键盘就得单独写一份驱动去翻译。全世界有成千上万的输入设备这种做法根本不可能持续。USB HID Usage Tables 的出现就是把“哪个功能对应哪个编号”这件事统一收归到一份公开文档里。厂商按表生产系统按表解析双方不用见面就能对上暗号。这份文档从 1996 年一路修订到 2022 年版本号走到 1.3中间经历了大量审查请求的合并。修订历史里能看到1.2 版本一次性纳入了四十多条审查请求1.3 版本又补充了显示器控制、街机设备数据格式、销售终端用法表等内容。这说明它不是拍脑袋写出来的而是行业里一批做键盘、鼠标、手柄、触摸屏的工程师反复磨合的结果。2.2 Usage Page 和 Usage ID两级编号的分工逻辑这份表的核心结构其实只有两层Usage Page用法页和 Usage ID用法编号。打个比方Usage Page 就像图书馆的“分区”比如“通用桌面区”“键盘区”“LED 区”“游戏控制区”Usage ID 则是每个分区里具体某本书的“书架号”。一个完整的用法由“页号 编号”共同确定单看编号是不够的。比如键盘按键在“键盘/小键盘页”页号 0x07里鼠标移动在“通用桌面页”页号 0x01里游戏手柄的按钮在“按钮页”页号 0x09里。这种分页设计的好处是不同领域的编号可以各自扩展互不干扰。键盘区把编号用完了不影响游戏区继续加新功能。// 一个简化的用法表示页号 用法编号 // 键盘页 0x07用法 0x04 代表字母 A uint16_t usage_a (0x07 16) | 0x04; // 通用桌面页 0x01用法 0x30 代表 X 轴 uint16_t usage_x (0x01 16) | 0x30;上面这段示意代码里高 16 位存页号低 16 位存用法编号合起来才是一个完整的“地址”。实际协议里页号和编号是分开传输的这里只是为了说明“两级定位”的思路。参数含义很直白页号决定去哪个领域找编号决定找哪个具体功能。2.3 报告描述符设备怎么告诉系统“我有哪些用法”光有词典还不够每个设备还得主动告诉操作系统“我身上有哪几个用法每个用法占几个字节、取值范围是多少。”这份“自我介绍”叫报告描述符Report Descriptor。它像一张装箱单写明了输入报告里第几位是左键、第几位是 X 轴位移。系统读到这张装箱单再对照 Usage Tables 里的编号含义就能正确解析数据。所以 Usage Tables 和报告描述符是配合使用的前者是词典后者是每个设备自己的说明书。词典统一了词义说明书说明了这个设备用了哪些词。3. 这份表里到底装了什么从键盘到街机的用法分类3.1 通用桌面页与键盘页最常用的两块地盘通用桌面页0x01管的是鼠标、键盘、摇杆这类“桌面级”设备的基础功能比如 X 轴、Y 轴、滚轮、左右键、系统电源控制等。键盘/小键盘页0x07则专门管按键从字母、数字到功能键、修饰键每个键一个编号。你按下的每一个键最终都落在这张表的某个格子里。除了这两块还有 LED 页0x08管键盘上的大小写指示灯、数字锁定灯按钮页0x09管手柄和鼠标上的按键消费类设备页则管多媒体按键比如音量加减、播放暂停。这些页各司其职合起来覆盖了绝大多数日常输入设备。3.2 仿真控制与游戏控制手柄、方向盘、飞行摇杆的编号归属仿真控制页0x02下面细分了体育仿真、飞行仿真、汽车仿真、坦克仿真、航海仿真、两轮仿真等子类。游戏控制页0x05则管三维游戏控制器、弹球机、光枪、游戏手柄。这些分类看起来细碎但正是它们让一个飞行摇杆的“俯仰轴”和一个汽车方向盘的“转向轴”能被系统区分开而不是笼统地都叫“某个轴”。打个比方这就像快递分拣先按大类分到“仿真”或“游戏”再按子类分到“飞行”或“汽车”最后按具体用法分到“俯仰”或“转向”。层级越细系统对设备的理解就越精确游戏里的操控映射也就越不容易翻车。3.3 版本 1.3 新增了什么显示器控制、销售终端与街机数据从修订历史看1.3 版本合并了多条审查请求把显示器控制类规范、开放式街机架构设备数据格式、销售终端用法表、电源设备用法表等内容纳入了进来。这意味着这份表不再只服务传统的键盘鼠标而是把触角伸到了显示器调节、收银设备、街机控制器等更宽的场景。对开发者来说这些新增分类的价值在于以前做这类设备可能得自己定义私有用法现在有了公开编号可循跨系统的兼容性就更有保障。当然私有用法并没有被禁止只是公开用法能让更多系统“天生认识”你的设备。3.4 用法类型标注线性控制、开关控制、选择器分别意味着什么表里每个用法还带类型标注比如线性控制LC、开关控制OOC、瞬时控制MC、选择器Sel、静态值SV、动态值DV等。这些标注不是摆设它们告诉系统这个用法在逻辑上该怎么对待。线性控制表示连续变化的量比如摇杆偏移开关控制表示只有开和关两种状态选择器表示从一组互斥选项里挑一个。通俗地说这就像给每个词标了词性是形容词连续量、是开关布尔量、还是单选题枚举量。系统据此决定用滑块、复选框还是下拉框来呈现也决定了数据解析时的边界判断。4. 容易搞混的几个概念Usage Page、Usage ID 与报告描述符的区别4.1 易混点一Usage Page 和 Usage ID 是不是一回事为什么混两个词都带“Usage”中文都叫“用法”初看像同义词。怎么区分Usage Page 是“领域分区”Usage ID 是“分区内的具体条目”。一个 Page 下挂很多 ID就像一章下挂很多小节。说“键盘页的 A 键”时页是 0x07ID 是 0x04缺一不可。只报 ID 不报页系统不知道你去哪个领域找。4.2 易混点二Usage Tables 和 Report Descriptor 谁管什么为什么混两者都出现在 HID 设备开发里都和“数据怎么解析”有关。怎么区分Usage Tables 是行业公共词典规定编号的含义Report Descriptor 是设备私有的装箱单规定这个设备用了哪些编号、每个占几位。词典是大家共用的装箱单是每个设备自己写的。设备可以只用词典里的一小部分词但不能篡改词义。4.3 易混点三HID 设备是不是只有键盘和鼠标为什么混日常接触最多的 HID 设备就是键鼠容易让人以为 HID 等于键鼠。怎么区分HID 是“人机交互设备”的统称游戏手柄、触摸屏、摇杆、方向盘、甚至某些传感器和显示器控制都归它管。Usage Tables 里光仿真控制就分了七八个子类远不止键鼠那点事。4.4 易混点四公开用法和厂商自定义用法能不能混用为什么混表里既有标准编号也允许厂商定义私有编号边界看起来模糊。怎么区分标准用法是“普通话”厂商自定义是“方言”。用普通话所有系统都能听懂用方言只有装了对应驱动的系统才懂。做通用设备优先用标准用法做特殊功能且不追求跨系统兼容时才考虑私有用法。提示遇到表里查不到的用法先确认是不是页号选错了再确认版本是否够新。1.3 相比早期版本补充了不少新分类旧资料可能查不到。5. 什么时候该翻这份表什么时候别硬套这份表最该翻的场景是你正在做或调一个 USB 输入设备需要确认某个功能有没有标准编号、该归到哪个页、类型标注是什么。比如做一个带旋钮的键盘旋钮该用“线性控制”还是“选择器”翻表比拍脑袋靠谱。又比如手柄的扳机键是归到按钮页还是仿真页的某个轴表里都有现成答案。它解决的是“编号对不上、系统认不出”这类问题属于开发前就该查清楚的资料。但也要说清楚边界如果你只是写上层应用通过系统提供的输入接口拿键值那这份表离你比较远不必硬啃。如果你做的是完全私有协议、不打算走 HID 类的设备这份表也不是必读。还有一种情况设备功能极其特殊标准用法里确实找不到对应项那就老老实实走厂商自定义别为了“用标准”而把功能拧成不伦不类的样子。我自己的习惯是每次动手画报告描述符之前先把要用到的每个功能在表里过一遍确认页号、编号、类型三样都对得上再开始写。有一次偷懒跳过了这一步结果把一个连续量标成了开关量系统里表现就是旋钮只能识别“转到头”和“没转到头”中间过程全丢了排查了半天才回到表里找到类型标注那一列。从那以后我每次定用法都强制走一遍“查页、查号、查类型”这三步再不敢凭印象填。希望这份整理能帮到你少走一点我走过的弯路。本文还有配套的精品资源点击获取