HID协议学习

HID协议学习

0. 文档资料

USB_HID协议中文版_USB接口HID设备_AUJsRmB9kg.pdf

HID+报告描述符精细说明_mgCxM8_ci9.pdf

hut1_22_U3cvnwn_ZZ.pdf

1. 基本概念

HID协议是一种基于USB的通讯协议,用于在计算机和输入设备之间进行数据传输。HID协议定义了标准的数据格式、命令结构以及传输方式,使得不同厂商生产的输入设备可以被操作系统识别和兼容。

  • HID协议的实现基于USB(Universal Serial Bus)接口,因此HID设备通常都是通过USB接口与计算机相连的。在HID协议中,设备会向计算机发送一系列的报告,描述设备的状态和用户的操作。计算机则可以根据这些报告来识别设备,并对用户的操作做出相应的响应。

  • HID协议支持的设备种类非常广泛,包括但不限于键盘、鼠标、游戏手柄、摄像头、扫描仪等等。这些设备都可以通过HID协议与计算机进行通信,从而实现与用户的交互。

2. 报告描述符详解

报表描述符定义了执行设备功能的数据格式和使用方法。
报表描述符和 USB 的其他描述符是不一样的,它不是一个简单的表格,报表描述符是 USB 所有描述符中最复杂的。报表描述符非常复杂而有弹性,因为它需要处理各种用途的设备。报表的数据必须以简洁的格式来储存,这样才不会浪费设备内的储存空间以及数据传输时的总线时间。实际上可以这样理解,报表内容的简洁,是通过报表描述符全面的、复杂的数据描述实现的。
报表描述符必须先描述数据的大小与内容。报表描述符的内容与大小因设备的不同而不同,在进行报表传输之前,主机必须先请求设备的报表描述符,只有得到了报表描述符才可正确解析报表的数据。报表描述符是报表描述项目(Item)的集合,每一个描述项目都有相对统一的数据结构,项目很多,通过编码实现

2.1 项目

在这里插入图片描述

见上图,报表描述符由描述 HID 设备的数据项目(Item)组成,项目的第一个字节(项目前缀)由三部分构成,即项目类型(item type)、项目标签(item tag)和项目长度(item size)。其中项目类型说明项目的数据类型,项目标签说明项目的功能,项目长度说明项目的数据部分的长度。
HID 的项目有短项目和长项目两种,其中短项目的格式如下图

在这里插入图片描述

短项目的数据字节数由 bSize 的值定义,bSize 为 0、1、2、3 时 Data 部分的字节数分别为 0、1、2、4 个字节。短项目的项目类型由 bType 定义,bType 为 0、1、2 时分别为 Main、Global 和 Local 类型。
长项目可以携带较多的数据,其格式如下图

在这里插入图片描述

项目中的第一个字节为上图中的特定值时表明该项目是一个长项目。长项目中的bDataSize 说明 Data 部分的字节数,bLongItemTag 在 HID 规范中没有定义。
下面是通过汇编实现的一个简单的报表描述符,描述符的每一行是一个项目,该描述符描述了一个从设备接收 2 个字节的输入报表和发送 2 个字节到设备的输出报表。

HID_Report_desc_table:
db 06h, A0h, FFh ; Usage Page(Vendor defined) 定义设备功能
db 09h, A5h ; Usage(Vendor Defined) 定义用法
db A1h, 01h ; Collection(Application) 开一个集合
db 09H, A6h ; Usage(Vendor defined) 定义用法
; 输入报表
db 09h, A7h ; Usgae(Vendor defined) 定义用法
db 15h, 80h ; Logical Minimum 定义输入最小值=-128
db 25h, 7Fh ; Logical Maximum 定义输入最大值=+127
db 75h, 08h ; Report Size 定义报表数据项大小=8
db 95h, 02h ; Report Count 定义报表数据向个数=2
db 81h, 02h ; Input(Data,Variable,Absolute) 输入项目
; 输出报表
db 09h, A9h ; Usgae(Vendor defined) 定义用法
db 15h, 80h ; Logical Minimum 定义输入最小值=-128
db 25h, 7Fh ; Logical Maximum 定义输入最大值=+127
db 75h, 08h ; Report Size 定义报表数据项大小=8
db 95h, 02h ; Report Count 定义报表数据向个数=2
db 91h, 02h ; Output(Data,Variable,Absolute) 输出项目
db C0h ; End Collection 关闭集合

2.2 项目分类

报表的项目有 MainGlobalLocal 三大类,每一类都有多个不同的项目,实现不同
的描述。
Main 类项目用于定义报表描述符中的数据项。也可以组合其中的若干数据项成为一个集合。Main 项目可以分为带数据的 Main 项目和不带数据的 Main 项目。带数据项的 Main用于生成报表中的数据项,包括 Input、Output 和 Feature 项目。不带数据的 Main 项目不生成报表中的数据项,包括 Collection 和 End Collection 项目。
Global 类项目实现对数据的描述,用来识别报表并且描述报表内的数据,包括数据的功能、最大与最小允许值以及数据项的大小与数目等。改变由 Main 类项目生成的项目状态表。Global 类项目描述对后续的所有项目有效,除非遇到有新的 Global 类项目。
Local 类项目定义控制的特征,这一类项目的作用域不超过下一个 Main 项目,所以在每一 Main 项目之前可能有多个 Local 项目。Local 项目用于描述后面的 Input、Output 和Feature 项目`

在这里插入图片描述

2.3报告描述符案例解析

案例1

static const u8 hidkey_report_map[] = {
    0x05, 0x0C,        // Usage Page (Consumer)
    0x09, 0x01,        // Usage (Consumer Control)
    0xA1, 0x01,        // Collection (Application)
    0x85, 0x01,        //   Report ID (1)
    0x09, 0xE9,        //   Usage (Volume Increment)
    0x09, 0xEA,        //   Usage (Volume Decrement)
    0x09, 0xCD,        //   Usage (Play/Pause)
    0x09, 0xE2,        //   Usage (Mute)
    0x09, 0xB6,        //   Usage (Scan Previous Track)
    0x09, 0xB5,        //   Usage (Scan Next Track)
    0x09, 0xB3,        //   Usage (Fast Forward)
    0x09, 0xB4,        //   Usage (Rewind)
    0x15, 0x00,        //   Logical Minimum (0)
    0x25, 0x01,        //   Logical Maximum (1)
    0x75, 0x01,        //   Report Size (1)
    0x95, 0x10,        //   Report Count (16)
    0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0xC0,              // End Collection
    // 35 bytes
};

例如看以上代码,ID设备的报告描述符(Report Descriptor)和一些使用该设备时可能需要的命名常量。报告描述符定义了所使用的HID协议中消费者设备(Consumer Device)的控制键,这些键包括音量调节、播放/暂停、静音、上一个/下一个曲目以及快进/快退。每个控制键由一个唯一的Usage ID(Usage Page + Usage ID)标识,并且在报告输入功能中使用1位来表示该键是否被按下。

这段代码定义了一个HID报告描述符,用于实现一组控制功能按键的映射。具体来说,它描述了一组使用Consumer Page的控制按键 Usage,并指定相应Usage的最小值、最大值、大小(占据多少比特)、数量等信息。

常量hidkey_report_map[]列出了描述符中的各个字段及其值:

  • 第1-2字节:Usage Page标识了所采用的设备类型(这里为0x0C,表示使用 Consumer Page)。

  • 第3-4字节:Usage标识了使用哪些控制按键(包括音量加减、播放/暂停、静音、上一曲、下一曲、快进、倒退)。

  • 第5-6字节:Collection字段说明后续定义的用途属于Application集合。类似于c语言的花括号

  • 第7字节:Report ID标识了该HID报告的唯一性,用于区分多个报告。

  • 第8~23字节:定义了使用的各个控制按键对应的Usage。

  • 第24~26字节:Logical Minimum指定了使用的控制按键取值的最小值(此处为0)。

  • 第27~29字节:Logical Maximum指定了使用的控制按键取值的最大值(此处为1)。

  • 第30字节:Report Size指定了每个Usage所占用的比特数(此处为1)。

  • 第31字节:Report Count指定了使用的Usage的数量(此处为16)。

  • 第32字节:Input字段说明了这一组控制按键的发送信息是从设备传输到主机的。

  • 第33字节:End Collection表示集合定义结束。类似于c语言的花括号

该HID报告描述符的作用在于,让USB主机知道如何解析来自HID设备的输入数据。通过正确解析描述符,实现与设备间的通信和交互。

// consumer key
#define CONSUMER_VOLUME_INC             0x0001
#define CONSUMER_VOLUME_DEC             0x0002
#define CONSUMER_PLAY_PAUSE             0x0004
#define CONSUMER_MUTE                   0x0008
#define CONSUMER_SCAN_PREV_TRACK        0x0010
#define CONSUMER_SCAN_NEXT_TRACK        0x0020
#define CONSUMER_SCAN_FRAME_FORWARD     0x0040
#define CONSUMER_SCAN_FRAME_BACK        0x0080

如看上述代码,在源码常量则将对应的控制键映射为了十六进制值,这些值可以用来生成报告数据并将其发送到主机。例如,按下音量增加键时,将使用0x0001值向主机发送包含音量增加键的报告数据。同样,通过检查从主机返回的报告数据,程序也可以知道用户是否按下了特定的控制键,以便在应用程序中执行相应的操作。那为什么0x0001可以对应音量升呢?那是因为是通过bit位来控制功能的发送,当发送的数据第一位为1时音量升高,第二位为1时音量降低,其余位都为0…具体可以看一下手绘图,这是一一对应的一个关系,这种对应关系也是官方自己定义的

在这里插入图片描述

比如发送一个 {0x00, 0x01}(相当于0x0001)的数据给usb,具体表现出来就是 音量加的功能。为什么?首先发送数据之前得知道需要发多少Bytes(发送多少Bytes = (Report Size * Report Count)/ 8);其次每一个Usage的值只能取0(Logical Minimum)或者1(Logical Maximum);那就可以知道如果要发送音量加就需要设置为{0x00, 0x01}。

在这里插入图片描述

案例2

static const u8 keyfob_report_map[] = {
    //通用按键
    0x05, 0x0C,        // Usage Page (Consumer)
    0x09, 0x01,        // Usage (Consumer Control)
    0xA1, 0x01,        // Collection (Application)
    0x85, 0x03,        //   Report ID (3)
    0x15, 0x00,        //   Logical Minimum (0)
    0x25, 0x01,        //   Logical Maximum (1)
    0x75, 0x01,        //   Report Size (1)
    0x95, 0x0B,        //   Report Count (11)
    0x0A, 0x23, 0x02,  //   Usage (AC Home)
    0x0A, 0x21, 0x02,  //   Usage (AC Search)
    0x0A, 0xB1, 0x01,  //   Usage (AL Screen Saver)
    0x09, 0xB8,        //   Usage (Eject)
    0x09, 0xB6,        //   Usage (Scan Previous Track)
    0x09, 0xCD,        //   Usage (Play/Pause)
    0x09, 0xB5,        //   Usage (Scan Next Track)
    0x09, 0xE2,        //   Usage (Mute)
    0x09, 0xEA,        //   Usage (Volume Decrement)
    0x09, 0xE9,        //   Usage (Volume Increment)
    0x09, 0x30,        //   Usage (Power)
    0x0A, 0xAE, 0x01,  //   Usage (AL Keyboard Layout)
    0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0x95, 0x01,        //   Report Count (1)
    0x75, 0x0D,        //   Report Size (13)
    0x81, 0x03,        //   Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0xC0,              // End Collection

    // 119 bytes
};

extern int ble_hid_data_send(u8 report_id, u8 *data, u16 len);

再来看这个案例,如果我们要实现Usage (AC Search)这个功能我们应该发送什么数据呢?依旧用位按键定位法,首先我们先算一下要发送多少字节的数据,可以看到有两个size和count,因此我们算出来的结果是111+131 = 24bit =3byte,因此我们要发送的字节数为3

在这里插入图片描述

而我们的操作数有12位,因此三字节发送的数据与之对应的是
0x000001(000000000000000000000001)—Usage (AC Home)
0x000002(000000000000000000000010)—Usage (AC Search)
0x000004(000000000000000000000100)—Usage (AL Screen Saver)
0x000008(000000000000000000001000)—Usage (Eject)
0x000100(000000000000000000010000)—Usage (Scan Previous Track)

如此往下一一按bit进行对应就可以实现自己的功能

以下是这个数组中每个数值(十六进制)的详细解释:

  • 0x05, 0x0C:使用页 (Usage Page) - Consumer。说明此hid report map定义了一个消费者设备类别。

  • 0x09, 0x01:使用 (Usage) - 消费器控制 (Consumer Control)。说明此hid report map定义了一个消费者控制按键。

  • 0xA1, 0x01:集合 (Collection) - 应用程序 (Application)。指定本HID report map包含应用程序类型的控件,并且相邻的USSAGE数据由同一集合处理。

  • 0x85, 0x03:报告 ID (Report ID) - 3。指定此hid report map定义的报告类型为ID号为3的报告。

  • 0x15, 0x00:逻辑最小值 (Logical Minimum) - 0。指定接收此报告的系统(如电脑)将接收到的字节映射到具有最小可能值的数字值。

  • 0x25, 0x01:逻辑最大值 (Logical Maximum) - 1。指定接收此报告的系统将接收到的字节映射到具有最大可能值的数字值。

  • 0x75, 0x01:报告大小 (Report Size) - 1。指定其中每个按键事件的报告数据位数是1位,即开/关状态。

  • 0x95, 0x0B:报告计数 (Report Count) - 11。指定此hid report map定义的报告中包括11个按键事件。

  • 0x0A, 0x23, 0x02:使用 (Usage) - AC Home。指定第一个按键对应于AC Home使用码,表示主页功能键。

  • 0x0A, 0x21, 0x02:使用 (Usage) - AC Search。指定第二个按键对应于AC Search使用码,表示搜索功能键。

  • 0x0A, 0xB1, 0x01:使用 (Usage) - AL Screen Saver。指定第三个按键对应于AL Screen Saver使用码,表示启动屏幕保护程序。

  • 0x09, 0xB8:使用 (Usage) - 弹出式按钮(Eject)。

  • 0x09, 0xB6:使用 (Usage) - 扫描上一曲目 (Scan Previous Track)。

  • 0x09, 0xCD:使用 (Usage) - 播放/暂停 (Play/Pause)。

  • 0x09, 0xB5:使用 (Usage) - 扫描下一曲目 (Scan Next Track)。

  • 0x09, 0xE2:使用 (Usage) - 静音 (Mute)。

  • 0x09, 0xEA:使用 (Usage) - 音量减小 (Volume Decrement)。

  • 0x09, 0xE9: 使用 (Usage) - 音量增大 (Volume Increment)。

  • 0x09, 0x30:使用 (Usage) - 电源 (Power)。

  • 0x0A, 0xAE, 0x01:使用 (Usage) - AL Keyboard Layout。指定最后一个按键对应于AL Keyboard Layout使用码,表示更改键盘布局。

  • 0x81, 0x02:输入 (Input) - 数据、变量、绝对值、没有回绕、线性、优先状态、无空位置

  • 0x95, 0x01:报告计数 (Report Count) - 1。指定此hid report map定义的报告中包括1个按键事件。

  • 0x75, 0x0D:报告大小 (Report Size) - 13。指定其中每个按键事件的报告数据位数是13位,即keyfob_report_map数组中11个字节(共88位)全部使用,报告数据位长为13位,其他5bits使用填充符号“0”进行填充。

  • 0x81, 0x03:输入 (Input) - 常量、变量、绝对值、没有回绕、线性、优先状态、无空位置。表示HID设备将输出一个全为0的字节作为该 Report ID 的最后一项,也就是按下按键后立即释放时触发的事件。因为退出报告只有该按键特殊事件,并需要调整指针来写入发送函数,所以状态应为常量。

  • 0xC0:结束集合 (End Collection)。指定此 hid report map 定义的集合结束。

参考资料

https://blog.csdn.net/pig10086/article/details/71438990

https://blog.csdn.net/lep150510/article/details/119572626

3.如何自己实现一个报告描述符实现一个功能呢?

参考

https://www.usbzh.com/article/detail-830.html

4. 特点

HID协议的优点包括以下几个方面:

  1. 简单易用:HID协议定义的指令和数据格式都很简单,易于理解并进行开发。对于绝大多数的输入设备,我们只需要遵循HID协议来实现输入输出即可。

  2. 高效性能:HID协议使用了一种类似于中断传输的方式,在需要时及时传输数据,降低了延迟,并保证了数据的实时性。这使得HID协议更适合用于实时性要求比较高的应用。

  3. 可靠性:HID协议的实现通常基于硬件设计,配合驱动程序和操作系统支持,使得输入设备能够与计算机无缝连接和互通。也因此HID协议具有高可靠性、稳定性等特点,提高了产品的品质。

此外,HID协议还支持多种输入设备类型(如键盘、鼠标、摇杆等),并且支持对输入设备进行配置和控制,如设置灯光、自定义按键功能等。

总的来说,HID协议是一种很好的通讯协议,使得输入设备的设计和使用更加简单、高效、可靠,同时也提高了用户的使用体验。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/28977.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何实现在线书签内容替换

书签广泛应用于企业的各种办公自动化业务场景中。例如:在范式合同模板中将甲乙方书签自动替换成具体的公司名称;在红头文件模板中将红头标题书签替换成具体的行政指令;在各种协议模板中将协议日期书签替换为当前日期;等等。 在这…

【Elacticsearch】 原理/数据结构/面试经典问题整理

对Elacticsearch 原理/数据结构/面试经典问题整理的文章; 映射 | Elasticsearch: 权威指南 | Elastic Elacticsearch介绍 Elasticsearch,这里简称ES。ES是一个开源的高可用高扩展的分布式全文搜索与分析引擎,可以提供PB级近实时的数据存储和检索能力&am…

《离散数学》:集合、关系和函数

〇、前言 这章将会对集合、以及集合之上的关系、以及两个集合之间的映射情况做一个细致的讨论。集合作为数学和其他领域中的基础概念,具有广泛的应用和重要的地位。它为数学建立了基本的体系和推理方法,为各个领域的研究和应用提供了一种统一的描述和分…

基于web漏洞扫描及分析系统设计_kaic

基于web漏洞扫描及分析系统设计 摘 要 随着信息技术的发展和网络应用在我国的普及,针对我国境内信息系统的恶意网络攻击也越来越多,并且随着黑客攻击技术的不断地更新,网络犯罪行为变得越来越难以应对,用户日常访问的网站是否安全…

Mysql主从复制及读写分离

🍓 简介:java系列技术分享(👉持续更新中…🔥) 🍓 初衷:一起学习、一起进步、坚持不懈 🍓 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正🙏 🍓 希望这篇文章对你有所帮助,欢…

LaTeX插入参考文献

接着上一篇,用EndNote组织参考文献,然后再导入到LeTex中感觉不太好用,然后就学习了一下BibTeX来管理参考文献,发现还可以,这里记录一下,方便以后查阅。 LaTeX插入参考文献 thebibliographyBibTeX参考资料 t…

前端 sentry 接入钉钉机器人

sentry 接入钉钉机器人 打开钉钉,添加机器人 此时会得到Webhook地址,记录一下,以后会用到 sentry 端设置 看看这里有木有钉钉插件,有的话开启插件,并配置这里我说一下没有的情况下,我们何如设置 这里需要填写webhook url 这个的url 需要是一个公网的地址,不可以是本地…

使用Unity开发一个独立的区块链

Arouse Blockchain [Unity独立区块链] ❗️千万别被误导,上图内容虽然都在项目中可寻,但与目前区块链的业务代码关联不大,仅供宣传作用(总得放些图看着好看)。之所以有以上内容是项目有个目标功能是希望每个用户在区块链上都有一个独一无二的…

View UI Plus (iview)表格单选实现教程

View UI Plus 是 View Design 设计体系中基于 Vue.js 3 的一套 UI 组件库,主要用于企业级中后台系统 View UI,即原先的 iView,从 2019 年 10 月起正式更名为 View UI,并使用全新的 Logo View UI Plus 实现表格单选,这…

首次使用云服务器搭建网站(二)

书接上文,我们已经完成了服务器的租赁,宝塔面板的下载与安装。 接下来我们将正式开始网站搭建。 一、网站创建 点击网站、添加站点 输入网站域名、数据库选择MySQL数据库,选择utf8,数据库账号密码会自动生成。无论你要创建什么样…

互联网行业-镭速文件传输系统方案

互联网行业是一个快速变化和高度竞争的行业,这一行业需要传输大量的数据、代码和文件。在互联网企业的生产和运营过程中,需要传输各种敏感和大型的文件,例如业务报告、数据分析、软件代码等。这些文件需要在不同的部门、不同的地点之间高效地…

用敏捷工具Leangoo领歌做敏捷需求管理

传统的瀑布工作模式使用详细的需求说明书来表达需求,需求人员负责做需求调研,根据调研情况编制详细的需求说明书,进行需求评审,评审之后签字确认交给研发团队设计开发。在这样的环境下,需求文档是信息传递的主体&#…

小雉系统U盘安装包制作

​ 本文原地址: http://www.feitianzhi.com/boke/index.php/archives/57/ 概述 小雉系统可从线上系统制作安装包到U盘,制作的安装包可用于新系统的安装; 小雉系统只提供升级包,对应的安装包均是客户在应用升级包后按本文或http://www.f…

vite预渲染 vite-plugin-prerender 大坑记录

本文部分配置转自:vite预渲染怎么实现_猿耳盗铃的博客-CSDN博客 懒得重新写,贴下版本和自己踩的各种坑吧 以下为版本,本文只给vite vue3的建议,不一定适用,因为正常情况能build成功,我昨天中午之前一直没…

招商基金资深架构师教你如何搭建统一监控平台

随着数字化进程的加速和业务的高速发展,系统的复杂程度日益升级,为确保业务系统的连续性和稳定性,越来越多的企业想要建设统一的监控平台,但却不知道从哪里开始着手。比如: 有些企业会直接将监控系统页面集成到统一监…

Jmeter实现Dubbo接口测试

目录 前言: 一、准备 二、编写我们的测试工程 三、Jmeter来测试这个工程 前言: JMeter可以用来测试Dubbo接口的性能和负载。Dubbo是阿里巴巴的高性能RPC框架,常用于分布式服务的调用。为了测试Dubbo接口,需要使用JMeter提供的…

为什么说2023年最难招聘的岗位是高性能计算工程师?

随着毕业季的临近,高校毕业生将进入就业关键阶段。据统计,2023届全国高校毕业生预计达到1158万人,同比增加82万人,再创新高。尽管有千万的大学毕业生,但是企业反馈依然很难招聘到合适的高性能计算工程师。 这主要归因于…

「OceanBase 4.1 体验」OceanBase:解读领先的分布式数据库系统,功能与体验全解析

文章目录 前言一、关于 【OceanBase 4.1】征文活动(可跳过)二、OceanBase 产品了解2.1 初识 OceanBase2.2 什么是 OceanBase2.3 OceanBase 相关链接2.4 OceanBase 与传统数据库对比有何特别之处2.5 OceanBase 相关概念以及术语2.5.1 OceanBase 基本概念2…

【Docker】什么是Docker,它用来干什么

作者简介: 辭七七,目前大一,正在学习C/C,Java,Python等 作者主页: 七七的个人主页 文章收录专栏: 七七的闲谈 欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖&#x1f…

软件测试面试题(大全)

1.B/S架构和C/S架构区别 B/S 只需要有操作系统和浏览器就行,可以实现跨平台,客户端零维护,维护成本低,但是个性化能力低,响应速度较慢 C/S响应速度快,安全性强,一般应用于局域网中,因…