USB HID Report Descriptor 报告描述符

2024-05-06 10:08

本文主要是介绍USB HID Report Descriptor 报告描述符,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

参照:https://www.cnblogs.com/AlwaysOnLines/p/3859557.html

报告描述符由一些数据片组成,这些数据片被叫做Item。每一个Item都包含一个字节的前缀,这个前缀中包含了三个信息【item tag、item type、item size】。

Item可以包含一个可选的数据段;Item的数据部分的长度取决于Item的基本类型。Item有两种基本类型:short item 和 long item

short item格式

short item第一字节包含size、byte、tag。第一个字节后面可以是0、1、2或4个可选数据字节,具体取决于size的大小。

bSize:指定后续数据字节个数;

bType:标识item的的类型;

bTag:标识item的具体功能;

long item格式

就像short item格式一样,long item格式第一字节包含size、byte、tag。long item格式使用一个特殊的item标记值来指示它是一个long item。long item的size(bDataSize)和tag(bLongItemTag)都用8bit表示。后面最多可包含255字节数据。

bSize(10b):固定为10b

bType(11b):保留为11b

bTag(1111b):固定为1111b

[bDataSize]:后续数据字节数

[bLongItemTag]:标签

重要提示:

此文档未定义tag标记,这些标记是为将来使用保留的。标记0xF0-0xFF由供应商定义

short item 的 item tags 有三种类型:Main, Global, and Local

Main Items:主项目

Main items 用于在报告描述符中定义或分组某些类型的数据字段。主要有两种类型:data 和 non-data。Datat-type main item 用于在报告描述符中创建Input,Output 和 Feature 字段。non-data不创建字段。

data type

 

non_data Type

Global Items:全域项目

Global items用于描述数据而不是定义数据。一个Main item假定了item项状态表的特性,Global items可以改变item项状态表的特性。因此,Global items应用于所有随后定义的item项,除非被其他Global items项覆盖。

Usage Page:指定当前Usage Page的无符号整数。因为usage是32位数据,为了节省描述符中的空间,通过高16bit来使用usage page项,低16bit表示usage id

Logical Minimum:以逻辑单位表示的范围值。这是变量或数组项将报告的最小值。例如,报告鼠标的x位置值从0到128的逻辑最小值为0,逻辑最大值为128

Physical Minimum:variable item项的物理范围的最小值。这表示应用了 units 的逻辑最小值。

Unit Exponent:以10为底的单位指数的值。有关详细信息,请参阅本节后面的表

Report Size:无符号整数,以位为单位指定报表字段的大小。这允许解析器为报表构建一个项目映射

 

Report Count:无符号整数,指定项的数据字段数;确定此特定项的报表中包含多少report。和因此report总加入了多少bit

Push:将global item状态表的副本放在堆栈上

Pop:将item项状态表替换为顶部

Local Items:区域项目

Local item tag 定义控件的特征。这些item项目不会结转到下一个Main item。如果一个Main item定义了多个控件,则它前面可能有几个类似的Local item tag。例如,一个Input item可能有几个与之相关联的Usage tag,每个控件一个。

Usage:item用途项的的Usage索引;item项 或 collection的建议用法。在一个item项表示多个控件的情况下,一个usage tag可能会建议对数组中的每个变量或元素使用

Usage Minimum:定义与数组或位图关联的起始usage

Designator Index:确定用于控件的正文部分。索引指向物理描述符中的designator

 

以下是一个USB鼠标的报告描述符 (该报告描述符号由HID Descriptor tool生成)

code char MouseReportDescriptor[63] = {

0x05, 0x01, // USAGE_PAGE (Generic Desktop)

0x09, 0x06, // USAGE (Keyboard)

0xa1, 0x01, // COLLECTION (Application) 这就是一个MAIN Item,可以对应上图查看

0x05, 0x07, // USAGE_PAGE (Keyboard)

0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)

0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)

0x15, 0x00, // LOGICAL_MINIMUM (0)

0x25, 0x01, // LOGICAL_MAXIMUM (1)

0x75, 0x01, // REPORT_SIZE (1)

0x95, 0x08, // REPORT_COUNT (8)

0x81, 0x02, // INPUT (Data,Var,Abs) 这就是一个MAIN Item,可以对应上图查看

0x95, 0x01, // REPORT_COUNT (1)

0x75, 0x08, // REPORT_SIZE (8)

0x81, 0x03, // INPUT (Cnst,Var,Abs) 这就是一个MAIN Item,可以对应上图查看

0x95, 0x05, // REPORT_COUNT (5)

0x75, 0x01, // REPORT_SIZE (1)

0x05, 0x08, // USAGE_PAGE (LEDs)

0x19, 0x01, // USAGE_MINIMUM (Num Lock)

0x29, 0x05, // USAGE_MAXIMUM (Kana)

0x91, 0x02, // OUTPUT (Data,Var,Abs) 这就是一个MAIN Item,可以对应上图查看

0x95, 0x01, // REPORT_COUNT (1)

0x75, 0x03, // REPORT_SIZE (3)

0x91, 0x03, // OUTPUT (Cnst,Var,Abs) 这就是一个MAIN Item,可以对应上图查看

0x95, 0x06, // REPORT_COUNT (6)

0x75, 0x08, // REPORT_SIZE (8)

0x15, 0x00, // LOGICAL_MINIMUM (0)

0x25, 0xFF, // LOGICAL_MAXIMUM (255)

0x05, 0x07, // USAGE_PAGE (Keyboard)

0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))

0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)

0x81, 0x00, // INPUT (Data,Ary,Abs) 这就是一个MAIN Item,可以对应上图查看

0xc0 // END_COLLECTION 这就是一个MAIN Item,可以对应上图查看

};

 

------------------------------------------------------------------------------------------------------------------------------------------------------------

 

参考:http://blog.chinaunix.net/uid-7762106-id-146787.html

 

在USB中,USB HOST是通过各种描述符来识别设备的,有设备描述符,配置描述符,接口描述符,端点描述符,字符串描述符,报告描述符等等。USB报告描述符(Report Descriptor)是HID设备中的一个描述符,它是比较复杂的一个描述符。

USB HID设备是通过报告来给传送数据的,报告有输入报告和输出报告。输入报告是USB设备发送给主机的,例如USB鼠标将鼠标移动和鼠标点击等信息返回给电脑,键盘将按键数据数据返回给电脑等;输出报告是主机发送给USB设备的,例如键盘上的数字键盘锁定灯和大写字母锁定灯等。报告是一个数据包,里面包含的是所要传送的数据。输入报告是通过中断输入端点输入的,而输出报告有点区别,当没有中断输出端点时,可以通过控制输出端点0发送,当有中断输出端点时,通过中断输出端点发出。

而报告描述符,是描述一个报告以及报告里面的数据是用来干什么用的。通过它,USB HOST可以分析出报告里面的数据所表示的意思。它通过控制输入端点0返回,主机使用获取报告描述符命令来获取报告描述符,注意这个请求是发送到接口Interface的,而不是到设备。一个报告描述符可以描述多个报告,不同的报告通过报告ID来识别,报告ID在报告最前面,即第一个字节。当报告描述符中没有规定报告ID时,报告中就没有ID字段,开始就是数据。更详细的说明请参看USB HID协议,该协议可从Http://www.usb.org下载。

USB报告描述符可以通过使用HID Descriptor tool来生成,这个工具可以到Http://www.usb.org下载.

下面通过由HID Descriptor tool生成的USB鼠标和USB键盘来说明一下报告描述符和报告。

code char KeyBoardReportDescriptor[63] = {

//表示用途页为通用桌面设备

0x05, 0x01, // USAGE_PAGE (Generic Desktop)

//表示用途为键盘

0x09, 0x06, // USAGE (Keyboard)

//表示应用集合,必须要以END_COLLECTION来结束它,见最后的END_COLLECTION

0xa1, 0x01, // COLLECTION (Application)

//表示用途页为按键

0x05, 0x07, // USAGE_PAGE (Keyboard)

//用途最小值,这里为左ctrl键

0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)

//用途最大值,这里为右GUI键,即window键

0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)

//逻辑最小值为0

0x15, 0x00, // LOGICAL_MINIMUM (0)

//逻辑最大值为1

0x25, 0x01, // LOGICAL_MAXIMUM (1)

//报告大小(即这个字段的宽度)为1bit,所以前面的逻辑最小值为0,逻辑最大值为1

0x75, 0x01, // REPORT_SIZE (1)

//报告的个数为8,即总共有8个bits

0x95, 0x08, // REPORT_COUNT (8)

//输入用,变量,值,绝对值。像键盘这类一般报告绝对值,

//而鼠标移动这样的则报告相对值,表示鼠标移动多少

0x81, 0x02, // INPUT (Data,Var,Abs)

//上面这这几项描述了一个输入用的字段,总共为8个bits,每个bit表示一个按键

//分别从左ctrl键到右GUI键。这8个bits刚好构成一个字节,它位于报告的第一个字节。

//它的最低位,即bit-0对应着左ctrl键,如果返回的数据该位为1,则表示左ctrl键被按下,

//否则,左ctrl键没有按下。最高位,即bit-7表示右GUI键的按下情况。中间的几个位,

//需要根据HID协议中规定的用途页表(HID Usage Tables)来确定。这里通常用来表示

//特殊键,例如ctrl,shift,del键等

 

//这样的数据段个数为1

0x95, 0x01, // REPORT_COUNT (1)

//每个段长度为8bits

0x75, 0x08, // REPORT_SIZE (8)

//输入用,常量,值,绝对值

0x81, 0x03, // INPUT (Cnst,Var,Abs)

//上面这8个bit是常量,设备必须返回0

 

//这样的数据段个数为5

0x95, 0x05, // REPORT_COUNT (5)

//每个段大小为1bit

0x75, 0x01, // REPORT_SIZE (1)

//用途是LED,即用来控制键盘上的LED用的,因此下面会说明它是输出用

0x05, 0x08, // USAGE_PAGE (LEDs)

//用途最小值是Num Lock,即数字键锁定灯

0x19, 0x01, // USAGE_MINIMUM (Num Lock)

//用途最大值是Kana,这个是什么灯我也不清楚^_^

0x29, 0x05, // USAGE_MAXIMUM (Kana)

//如前面所说,这个字段是输出用的,用来控制LED。变量,值,绝对值。

//1表示灯亮,0表示灯灭

0x91, 0x02, // OUTPUT (Data,Var,Abs)

 

//这样的数据段个数为1

0x95, 0x01, // REPORT_COUNT (1)

//每个段大小为3bits

0x75, 0x03, // REPORT_SIZE (3)

//输出用,常量,值,绝对

0x91, 0x03, // OUTPUT (Cnst,Var,Abs)

//由于要按字节对齐,而前面控制LED的只用了5个bit,

//所以后面需要附加3个不用bit,设置为常量。

 

//报告个数为6

0x95, 0x06, // REPORT_COUNT (6)

//每个段大小为8bits

0x75, 0x08, // REPORT_SIZE (8)

//逻辑最小值0

0x15, 0x00, // LOGICAL_MINIMUM (0)

//逻辑最大值255

0x25, 0xFF, // LOGICAL_MAXIMUM (255)

//用途页为按键

0x05, 0x07, // USAGE_PAGE (Keyboard)

//使用最小值为0

0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))

//使用最大值为0x65

0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)

//输入用,变量,数组,绝对值

0x81, 0x00, // INPUT (Data,Ary,Abs)

//以上定义了6个8bit宽的数组,每个8bit(即一个字节)用来表示一个按键,所以可以同时

//有6个按键按下。没有按键按下时,全部返回0。如果按下的键太多,导致键盘扫描系统

//无法区分按键时,则全部返回0x01,即6个0x01。如果有一个键按下,则这6个字节中的第一

//个字节为相应的键值(具体的值参看HID Usage Tables),如果两个键按下,则第1、2两个

//字节分别为相应的键值,以次类推。

//关集合,跟上面的对应

0xc0 // END_COLLECTION

};

 

通过上面的分析,我们知道这个报告中只有一个报告,所以没有报告ID,因此返回的都是实际使用的数据。总共有8字节输入,1字节输出。其中输入的第一字节用来表示特殊按键,第二字节保留,后面的六字节为普通按键。如果只有左ctrl键按下,则返回01 00 00 00 00 00 00 00(十六进制),如果只有数字键1 按下,则返回00 00 59 00 00 00 00 00,如果数字键1 和2 同时按下,则返回00 00 59 5A 00 00 00 00,如果再按下左shift 键,则返回02 00 59 5A 00 00 00 00,然后再释放1 键,则返回02 00 5A 00 00 00 00 00,然后全部按键释放,则返回00 00 00 00 00 00 00 00。这些数据(即报告)都是通过中断端点返回的。当按下Num Lock键时,PC会发送输出报告,从报告描述符中我们知道,Num Lock的LED对应着输出报告的最低位,当数字小键盘打开时,输出xxxxxxx1(二进制,打x的由其它的LED状态决定);当数字小键盘关闭时,输出xxxxxxx0(同前)。取出最低位就可以控制数字键锁定LED了。

 

下面这个报告描述符是USB鼠标报告描述符,比起键盘的来说要简单些。它描述了4个字节,第一个字节表示按键,第二个字节表示x轴(即鼠标左右移动,0表示不动,正值表示往右移,负值表示往左移),第三个字节表示y轴(即鼠标上下移动,0表示不动,正值表示往下移动,负值表示往上移动),第四个字节表示鼠标滚轮(正值为往上滚动,负值为往下滚动)。

code char MouseReportDescriptor[52] = {

//通用桌面设备

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)

//使用最小值1

0x19, 0x01, // USAGE_MINIMUM (Button 1)

//使用最大值3。1表示左键,2表示右键,3表示中键

0x29, 0x03, // USAGE_MAXIMUM (Button 3)

//逻辑最小值0

0x15, 0x00, // LOGICAL_MINIMUM (0)

//逻辑最大值1

0x25, 0x01, // LOGICAL_MAXIMUM (1)

//数量为3

0x95, 0x03, // REPORT_COUNT (3)

//大小为1bit

0x75, 0x01, // REPORT_SIZE (1)

//输入,变量,数值,绝对值

//以上3个bit分别表示鼠标的三个按键情况,最低位(bit-0)为左键

//bit-1为右键,bit-2为中键,按下时对应的位值为1,释放时对应的值为0

0x81, 0x02, // INPUT (Data,Var,Abs)

 

//填充5个bit,补足一个字节

0x95, 0x01, // REPORT_COUNT (1)

0x75, 0x05, // REPORT_SIZE (5)

0x81, 0x03, // INPUT (Cnst,Var,Abs)

 

//用途页为通用桌面

0x05, 0x01, // USAGE_PAGE (Generic Desktop)

//用途为X

0x09, 0x30, // USAGE (X)

//用途为Y

0x09, 0x31, // USAGE (Y)

//用途为滚轮

0x09, 0x38, // USAGE (Wheel)

//逻辑最小值为-127

0x15, 0x81, // LOGICAL_MINIMUM (-127)

//逻辑最大值为+127

0x25, 0x7f, // LOGICAL_MAXIMUM (127)

//大小为8个bits

0x75, 0x08, // REPORT_SIZE (8)

//数量为3个,即分别代表x,y,滚轮

0x95, 0x03, // REPORT_COUNT (3)

//输入,变量,值,相对值

0x81, 0x06, // INPUT (Data,Var,Rel)

 

//关集合

0xc0, // END_COLLECTION

0xc0 // END_COLLECTION

};

 

通过对上面的报告分析,我们知道报告返回4个字节,没有报告ID。如果鼠标左键按下,则返回01 00 00 00(十六进制值),如果右键按下,则返回02 00 00 00,如果中键按下,则返回04 00 00 00,如果三个键同时按下,则返回07 00 00 00。如果鼠标往右移动则第二字节返回正值,值越大移动速度越快。其它的类推。

 

这里只对报告描述符做一个简单的介绍,更详细的资料请参看USB HID协议以及HID Usage Tables,

可以从Http://www.usb.org下载。

 

根据这个实际设计的USB键盘和USB鼠标:

 

USB键盘:

user1/2198/archives/2007/36484.html

 

http://www.ednchina.com/blog/computer00/20134/message.aspx

 

USB鼠标:

user1/2198/archives/2007/36520.html

 

http://www.ednchina.com/blog/computer00/20135/message.aspx

 

这篇关于USB HID Report Descriptor 报告描述符的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/964077

相关文章

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

OpenCV结构分析与形状描述符(11)椭圆拟合函数fitEllipse()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C++11 算法描述 围绕一组2D点拟合一个椭圆。 该函数计算出一个椭圆,该椭圆在最小二乘意义上最好地拟合一组2D点。它返回一个内切椭圆的旋转矩形。使用了由[90]描述的第一个算法。开发者应该注意,由于数据点靠近包含的 Mat 元素的边界,返回的椭圆/旋转矩形数据

Python:豆瓣电影商业数据分析-爬取全数据【附带爬虫豆瓣,数据处理过程,数据分析,可视化,以及完整PPT报告】

**爬取豆瓣电影信息,分析近年电影行业的发展情况** 本文是完整的数据分析展现,代码有完整版,包含豆瓣电影爬取的具体方式【附带爬虫豆瓣,数据处理过程,数据分析,可视化,以及完整PPT报告】   最近MBA在学习《商业数据分析》,大实训作业给了数据要进行数据分析,所以先拿豆瓣电影练练手,网络上爬取豆瓣电影TOP250较多,但对于豆瓣电影全数据的爬取教程很少,所以我自己做一版。 目

开题报告中的研究方法设计:AI能帮你做什么?

AIPaperGPT,论文写作神器~ https://www.aipapergpt.com/ 大家都准备开题报告了吗?研究方法部分是不是已经让你头疼到抓狂? 别急,这可是大多数人都会遇到的难题!尤其是研究方法设计这一块,选定性还是定量,怎么搞才能符合老师的要求? 每次到这儿,头脑一片空白。 好消息是,现在AI工具火得一塌糊涂,比如ChatGPT,居然能帮你在研究方法这块儿上出点主意。是不

【干货分享】基于SSM的体育场管理系统的开题报告(附源码下载地址)

中秋送好礼 中秋佳节将至,祝福大家中秋快乐,阖家幸福。本期免费分享毕业设计作品:《基于SSM的体育场管理系统》。 基于SSM的体育场管理系统的开题报告 一、课题背景与意义 随着全民健身理念的深入人心,体育场已成为广大师生和社区居民进行体育锻炼的重要场所。然而,传统的体育场管理方式存在诸多问题,如资源分配不均、预约流程繁琐、数据统计不准确等,严重影响了体育场的使用效率和用户体验。

Usb Audio Device Descriptor(10) Hid Device

对于 Standard Interface Descriptor, 当 bInterfaceClass=0x03时,即为HID设备。Standard Interface Descriptor如下 struct usb_standard_interface_descriptor{U8 bLength; /*Size of this descriptor in bytes*/U8 bDescrip

Android rk3399 UAC(USB Audio)开发笔记

一、UAC有1.0和2.0,因Windows对2.0支持不好,我使用的是UAC1.0驱动 内核配置:CONFIG_USB_CONFIGFS_F_UAC1          ---这个宏配置无需物理codec,使用虚拟 alsa codec  驱动路径:"kernel\drivers\usb\gadget\function\f_uac1.c" 内核配置:CONFIG_USB_CONFIGFS_

多款式随身WiFi如何挑选,USB随身WiFi、无线电池随身WiFi、充电宝随身WiFi哪个好?优缺点分析!

市面上的随身WiFi款式多样琳琅满目,最具代表性的就是USB插电款、无线款和充电宝款。今天就来用一篇文章分析一下这三种款式的优缺点。 USB插电款 优点:便宜,无需充电,在有电源的地方可以随时随地插电使用,比如中兴的USB随身WiFi。 缺点:无电源的情况下,无法带出门使用,部分品牌考虑到这个问题,会配备一个充电仓,这个充电仓相对来说就有点累赘了。网速上也不太稳定,波动比较大。

【中国国际航空-注册/登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 1. 暴力破解密码,造成用户信息泄露 2. 短信盗刷的安全问题,影响业务及导致用户投诉 3. 带来经济损失,尤其是后付费客户,风险巨大,造成亏损无底洞 所以大部分网站及App 都采取图形验证码或滑动验证码等交互解决方案, 但在机器学习能力提高的当下,连百度这样的大厂都遭受攻击导致点名批评, 图形验证及交互验证方式的安全性到底如