USB HID协议中文版——USB接口HID设备

更新时间:2024-05-30 01:02:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

第8章 USB接口HID设备

HID(Human Interface Device,人机接口设备)是USB设备中常用的设备类型,是直接与人交互的USB设备,例如键盘、鼠标与游戏杆等。在USB设备中,HID设备的成本较低。另外,HID设备并不一定要有人机交互功能,只要符合HID类别规范的设备都是HID设备。

Wndows操作系统最先支持的HID设备。在windows 98以及后来的版本中内置有 HID设备的驱动程序,应用程序可以直接使用这些驱动程序来与设备通信。

在设计一个USB接口的计算机外部设备时,如果HID类型的设备可以满足需要,可以将其设计为HID类型设备,这样可以省去比较复杂的USB驱动程序的编写,直接利用Windows操作系统对标准的HID类型USB设备的支持。

8.1 HID设备简介

8.1.1 HID设备的特点

? 交换的数据储存在称为报表(Report)的结构内,设备的固件必须支持HlD报表的

格式。主机通过控制和中断传输中的传送和请求报表来传送和接收数据。报表的格式非常灵活。

? 每一笔事务可以携带小量或中量的数据。低速设备每一笔事务最大是8B,全速设

备每一笔事务最大是64B,高速设备每一笔事务最大是1024B。一个报表可以使用多笔事务。

? 设备可以在未预期的时间传送信息给主机,例如键盘的按键或是鼠标的移动。所以

主机会定时轮询设备,以取得最新的数据。

? HID设备的最大传输速度有限制。主机可以保证低速的中断端点每10ms内最多1

笔事务,每一秒最多是800B。保证全速端点每lms一笔事务,每一秒最多是64000B。保证高速端点每125 us三笔事务,每一秒最多是24.576MB。

? HID设备没有保证的传输速率。如果设备是设置在10ms的时距,事务之间的时间

可能等于或小于10ms。除非设备是设置在全速时在每个帧传输数据,或是在高速时在每个微帧传输数据。这是最快的轮询速率,所以端点可以保证有正确的带宽可供使用。

HID设备除了传送数据给主机外,它也会从主机接收数据。只要能够符合HlD类别规范的设备都可以是HID设备。

设备除了HlD接口之外,它可能同时还包含有其他的USB接口。例如影像显示设备可能使用HID接口来做亮度、对比度的软件控制,而使用传统的影像接口来传送要显示的数据。USB扩音器可以使用实时传输来播放语音,同时使用HID接口来控制音量、低音等。

HID类别设备的规范文件主要是以下两份:

? Device Class Definition for Human interface Devices ? HID Usage Tables

其中前者是HID的基本规范文件,后者可以是前者的附件,为开发人员提供实际的控制类型的描述。文件是用来定义让主机了解以及使用HID数据的数值。这两份文件是由 USB Device Working Group制定的,可以在网址http://www.usb.org/developers/hidpage/ #Class _Definition下载。

182 计算机高级接口实践

8.1.2 HID设备的硬件要求

HID接口必须符合Device Class Definition for Human interface Devices规范内所定义的HID类别的需求。在此文件内描述了所需的描述符、传输的频率以及传输的类型等。为了符合规范,HID接口的端点与描述符都必须符合数个要求。

所有的HID传输都是使用默认控制管道或是一个中断管道,HID设备必须有一个中断输入端点来传送数据到主机,中断输出端点则不是必需的。

主机 HID类别 驱动程序 外设 默认控制管道 HID类别 设备 中断管道 图8-1 HID传输的传输类型

表8-1 HID设备的传输类型 传输 类型 控制 中断 数据来源 设备(输入) 主机(输出) 设备(输入) 主机(输出) 数据类型 没有严格时间限制的数据 没有严格时间限制的数据 或是没有中断输出管道时的任何数据 定时或低延迟的数据 定时或低延迟的数据 是否需 要管道 是 是 是

主机与设备之间所交换的数据,可以分成两种类型:

? 低延迟的数据,必须尽快地到达目的;

? 配置或其他的数据,没有严格时间限制的需求。

中断管道是控制管道之外的另一种数据交换的方式,特别适合使用在接收端需要定时或是尽可能及时收到数据的时候。中断输入管道携带数据到主机,中断输出管道则是携带数据到设备。在总线忙的时候,控制管道可能会被延迟,而中断管道保证会有可得到的带宽。HID不需要一定有中断输出管道。如果没有中断输出管道,主机会在控制管道上使用HID设备特有的Set_Report请求来传送所有的报表。

8.1.3 HID固件的要求

主机的驱动程序要与HID设备通信,设备的固件必须符合下列需求:

? 设备的描述符必须识别该设备包含有HID接口。

? 除了默认控制管道外,固件必须另外支持一个中断输入管道。 ? 固件必须包含一个报表描述符来定义要传送与接收的设备数据。

如果要传送数据,固件必须支持Get_Report控制传输与中断输入传输。如果要接收数据,固件必须支持Set_Report控制传输与选择性的中断输出传输。

所有的HID数据都必须使用定义过的报表格式来定义报表中数据的大小与内容。设备可以支持一个或多个报表。在固件中的一个报表描述符用来描述此报表,以及如何使用报表数据的信息。

第8章 USB接口HID设备 183

在每一个报表中的一个数值,定义此报表是一个输入(Input)、输出(Output)或是特征(Feature)报表。主机在输入报表中接收数据,在输出报表中传送数据,特征报表可以在任何方向传递。

Windows 98以及后来版本的HID驱动程序使用中断传输来传递输入报表。输出报表的传输类型要根据设备支持的端点与Windows的版本而定。Windows 98 Gold只符合HID 1.0规范,它的HID驱动程序使用控制传输来传递输出报表。Windows 98 SE、Wndows 2000符合HID 1.1规范,HID驱动程序在有中断输出端点时使用中断传输,否则使用控制传输来传递输出报表。特征报表都是使用控制传输。

8.2 HID设备描述符

HID设备连接到USB主机后,主机通过发送Get_Descriptor请求读取HID设备的描述符,了解描述符对了解USB设备是至关重要的。

8.2.1 HID设备的描述符

HID设备除了支持USB设备的5种标准描述符之外,还支持HID设备特有的3种描述符。这些描述符是:

? USB标准描述符:设备、配置、接口、端点和字符串描述符。

? HID特有的描述符:HID、报表(Report)和实体(Physical)描述符。 从描述符的关联关系看,HID描述符是关联于接口。所以如果一个HID设备有2个端点,设备不需要每个端点有一个HID描述符。

接口描述符Interface HID描述符 Hid 端点描述符 Endpoint 报表描述符 Report 实体描述符 Physical HID、报表和实体描述符是HID设备特有的描述符 图8-2 HID描述符的关联关系

从前面的USB描述符可以看出一个规律,描述符的第一、二字节分别是描述符的长度和类型,描述符的类型字段(bDescriptorType)表明描述符的种类,下表列出了不同描述符的类型字段数值。

表8-2 HID的描述符

184 计算机高级接口实践 类型 描述符 设备 Device 配置 Configuration 字符串 String 接口 Interface 端点 Endpoint 设备限定 Device_Qualiffier Other_Speed_Configuration Interface_power HID Hub 报表 Report 实体 Physical 应用 所有设备必须有,只能一个 所有设备必须有,至少一个 可选择 每一个接口一个 除端点0之外的每个端点一个 同时支持全速与高速的设备必须有一个 HID设备必须有 HID设备必须有 可选择的 数值 01 02 03 04 05 06 07 08 21 29 22 23 标准 类别 HID 特定 对于一个HID设备,设备描述符与配置描述符没有HID特定的信息。其设备描述符的bDeviceClass和bDeviceSubClass字段的值为0,接口描述符的bInterfaceClass字段值为03,表示设备的该接口是HID类别。在接口描述符中其他包含HID特定信息的字段还有子类别码(blnterfaceSubClass)与协议码(blnterfaceProtocol字段)。

在接口描述符中子类别码字段等于1表示此设备支持启动接口(Boot Interface)。如果设备有启动接口,即便主机的HID没有加载驱动程序,设备也可以使用。这种情形可能发生在计算机是由DOS直接启动,在启动时观看系统设置画面或使用Wndows的安全模式时。

含有启动接口的键盘或鼠标可以使用BIOS或许多主机支持的默认简单协议。HID规范定义了键盘与鼠标的启动接口协议。

如果设备没有启动接口,并且接口描述符中协议码字段是1,表示设备支持键盘接口,协议码字段是2,表示支持鼠标接口。接口描述符中协议码字段是0,表示设备不支持启动协议。

在 HID Usage Tables规范中定义了键盘与鼠标的启动描述符(Boot Descriptor)。BIOS不需要从设备中读取描述符,因为它知道启动协议,并且假设设备支持启动协议。所以要启动的设备不需要在固件内包含启动接口描述符,它只要在主机尚未要求在报表描述符中的定义协议时支持启动协议即可。在操作系统加载HlD驱动程序后会使用Set_Protocol请求,将设备由启动协议转换成报表协议。

8.2.2 HID描述符

HID描述符的主要作用是用来识别HID通信所使用的额外描述符。下表是HID描述符结构。

偏移 量 0 1 2 4 5 6 7 字段 bLength bDescriptorType bcdHID bCountryCode bNumDescriptors bDescriptorType wDescriptorLength 表8-3 HID描述符结构 字节 数值 说明 数 类型 1 Numeric 描述符字节数 1 Constant 0x21 = HID描述符 2 Numeric HID规范版本号(BCD) 1 Numeric 硬件设备所在国家的国家代码 1 Numeric 类别描述符数目(至少有一个报表描述符) 1 Constant 类别描述符的类型 2 Numeric 报表描述符的总长度 第8章 USB接口HID设备 185 9 10 [bDescriptorType]... [wDescriptorLength]... 1 2 Constant 附加的描述符的类型,可选的 Numeric 附加的描述符的总长度,可选的 bcdHID:设备与其描述符所遵循的HID规范的版本号码,此数值是4个16进位的BCD格式字符。例如版本1.1的bcdHID是0110h。

bCountryCode:硬件目的国家的识别码。如果不说明,该字段为0。 bDescriptorType:HID描述符附属的描述符的类型(报表或实体)。每一个 HID都必须至少支持一个报表描述符。一个接口可以支持多个报表描述符,以及一个或多个实体描述符。

HID描述符的偏移量为9和10的bDescriptorType和wDescriptorLength可以重复存在多个。

1. 报表描述符

报表描述符定义了执行设备功能的数据格式和使用方法。

报表描述符和USB的其他描述符是不一样的,它不是一个简单的表格,报表描述符是USB所有描述符中最复杂的。报表描述符非常复杂而有弹性,因为它需要处理各种用途的设备。报表的数据必须以简洁的格式来储存,这样才不会浪费设备内的储存空间以及数据传输时的总线时间。

实际上可以这样理解,报表内容的简洁,是通过报表描述符全面的、复杂的数据描述实现的。

报表描述符必须先描述数据的大小与内容。报表描述符的内容与大小因设备的不同而不同,在进行报表传输之前,主机必须先请求设备的报表描述符,只有得到了报表描述符才可正确解析报表的数据。

报表描述符是报表描述项目(Item)的集合,每一个描述项目都有相对统一的数据结构,项目很多,通过编码实现。

(1)项目

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

HID的项目有短项目和长项目两种,其中短项目的格式如下图。

位序 字段

7 6 5 4 3 2 1 0

Data (可以是0、1、2、4个字节) bTag bType bSize 图8-3 HID报表短项目格式

短项目的数据字节数由bSize的值定义,bSize为0、1、2、3时Data部分的字节数分别为0、1、2、4个字节。短项目的项目类型由bType定义,bType为0、1、2时分别为Main、Global和Local类型。

长项目可以携带较多的数据,其格式如下图。

186 计算机高级接口实践

位序 字段 字节数

7 6 5 4 3 2 1 0

Data 1~255 bLongItemTag 1 bDataSize 1 1 1 1 1 1 1 0 1 1 图8-4 HID报表长项目格式

项目中的第一个字节为上图中的特定值时表明该项目是一个长项目。长项目中的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 定义输入最大值=+27 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 定义输入最大值=+27 db 75h, 08h ; Report Size 定义报表数据项大小=8 db 95h, 02h ; Report Count 定义报表数据向个数=2 db 91h, 02h ; Output(Data,Variable,Absolute) 输出项目 db C0h ; End Collection 关闭集合

(2)项目的分类

报表的项目有Main、Global和Local三大类,每一类都有多个不同的项目,实现不同的描述。

Main类项目用于定义报表描述符中的数据项。也可以组合其中的若干数据项成为一个集合。Main项目可以分为带数据的Main项目和不带数据的Main项目。带数据项的Main用于生成报表中的数据项,包括Input、Output和Feature项目。不带数据的Main项目不生成报表中的数据项,包括Collection和End Collection项目。

Global类项目实现对数据的描述,用来识别报表并且描述报表内的数据,包括数据的功能、最大与最小允许值以及数据项的大小与数目等。改变由Main类项目生成的项目状态表。Global类项目描述对后续的所有项目有效,除非遇到有新的Global类项目。

Local类项目定义控制的特征,这一类项目的作用域不超过下一个Main项目,所以在每一Main项目之前可能有多个Local项目。Local项目用于描述后面的Input、Output和Feature项目。

第8章 USB接口HID设备 187

下表列出的是全部的项目的前缀字和简要功能说明。 项目 类型 项目标志(Tag) Input Main 类项目 Output Feature Collection End Collection 表8-4 HID项目列表 项目前缀,nn功能说明 为数据长度 定义输入报表,主机利用该信息解析设备提供的数1000 00 nn 据。主机向控制端口发送Get_Report实现输入 创建输出报表,通过向设备发送Set_Report实现输1001 00 nn 出 定义送往设备的设置信息 1011 00 nn 定义2个以上数据(Input、Output和Feature)的1010 00 nn 关系为集合,Collection开始一个集合,之后的End Collection结束集合。Collection项目的数据部分说1100 00 nn 明Collection的类型 0000 01 nn 0001 01 nn 0010 01 nn 0011 01 nn 0100 01 nn 0101 01 nn 0110 01 nn 0111 01 nn 1000 01 nn 1001 01 nn 1010 01 nn 1011 01 nn 1100 01 nn – 1111 01 nn 0000 10 nn 0001 10 nn 0010 10 nn 0011 10 nn 0100 10 nn 0101 10 nn 0111 10 nn 1000 10 nn 1001 10 nn 1010 10 nn 1010 10 nn – 1111 10 nn Usage Page Logical Minimum Logical Maximum Physical Minimum Global Physical Maximum 类项Unit Exponent 目 Unit Report Size Report ID Report Count Push Pop Usage Usage Minimum Usage Maximum Designator Index Designator Minimum Designator Maximum String Index String Minimum String Maximum Delimiter 指定设备的功能 另外由于Usage项目有32位数据值,Usage Page项目用于为Usage项目在报表描述符中占居存储空间。用于存放后续的Usage项目的高16位。 定义变量或数组项目的逻辑最小值和最大值 定义变量或数组项目的物理最小值和最大值,分别和Logical Minimum、Logical Maximum对应 定义数值是基于10的指数 单位 指定报表数据区域所包含的位数 报表ID,该项目在报表中插入一个字节的报表ID 报表中数据域的数目 将Global项目状态表送入堆栈 从堆栈恢复Global项目状态表 保留 用法索引值,表示对项目或集合建议的用法,用于当一个项目描述多个控制,对每一个变量和数组元素都有建议的用法 定义阵列或位图中控制操作的第一个和最后一个用法 确定用于控制的实体,指向物理描述符中的目标 定义阵列或位图目标的起始和终止索引值 确定字符串描述符中的索引值 定义用于阵列或位图控制中字符串序列索引值的最小值和最大值 定义一组Local项目的开始和结束,1=开始,0=结束 保留 Local 类项目 在这些项目中,Usage Page用来指定设备的功能,而Usage项目用来指定个别报表的功能。Usage Page项目相当于是HID的子集合,Usage相当于是Usage Page的子集合。

2. 报表描述符的项目

188 计算机高级接口实践

(1)Input、Outpot和Feature项目

这3个项目用来定义报表中的数据字段。

Input项目可以应用到任何控制、计数器读数或其他设备传给主机的信息。一个输入报表包含一个或多个Input项目,主机使用中断输入传输来请求输入报表。

Ouput项目用来定义主机传送给设备的信息。一个输出报表包含一个或多个Outpot项目。输出报表包含控制状态的数据。如果有中断输出管道,HID1.1兼容主机使用中断输出传输来传送输出报表,否则使用Set_Report控制请求。

Feature项目应用到主机传送给设备的信息,或是主机从设备读取Feature项目。一个特征报表包含一个或多个Feature项目,Feature项目通常是包合影响设备与其组件整体行为的配置。特征报表通常是控制可以使用实际的控制面板调整的设置,例如主机可以使用虚拟控制面板来让用户选择控制特征。主机使用 Set_Report与Get_Report请求来传送与接收特征报表。

在每一个Input、Output和Feature项目的前缀字之后是32位描述数据,目前最多定义了9个位,余的位则是保留。位0~8的定义中只有位7不能应用于Input项目,除此之外其他的位定义都适应于Input、Output和Feature项目。

位 0 值 0 1 0 1 1 0 2 1 3 ① 4 ① 5 ① 0 1 0 1 0 1 0 6 ① 1 表8-5 Input、Output和Feature项目的数据项说明 数据字段 含义说明 名称 数据:表示项目的内容是可更改的(读/写)。 Data Constant 常数:表示项目的内容是不可更改的(只读)。 数组:报告全部控制的状态。如在键盘报表中每一个键在报表中Array 占一位,报表传输全部键的状态,可以同时按下任意多个键。 变量:报告作用中的控制。如在键盘报表中只报告按下的键的编号,可以同时按下的键的数目等于报表的计数(Global类项目Variable Report Count) 绝对:表示数值以一个固定值为基准。游戏杆通常是报告绝对数Absolute 据(游戏杆目前的位置)。 相对:表示数据的改变以上一个读数为基准。鼠标通常是报告相Relative 对数据(鼠标的移动位置)。 No Wrap 如果设置为1表示回转,当数值超过最小值到最大值的范围时将回转,如果最小值是0而最大值是10,超过最大值的下一个数Wrap 值是0。 线形:表示测量的数据与报表的数据有线性的关系。 Linear Non-Linear 非线性:表示测量的数据与报表的数据没有线性的关系。 优选状态:表示控制在没有用户交互时会回到一个特定的状态。Preferred 如按钮就有优选状态,在无操作时保持未按下的状态。 非优选状态:它维持在上一个用户选择的状态。如交替的开关就Non-Preferred 没有优选状态。 No Null Position 无空状态位置:表示控制永远在传送有效的数据。 空状态:表示控制支持一个没有传送有效数据的状态。如操纵杆可能具有一个多方向的按钮开关,在没有按下时在空状态,这时Null State 控制将传送一个在 Logical Minimum与Logical Maximum范围之外的数值来表示它在空状态。 不可变的:表示设备只有在主机请求时才改变数值。当主机传送一个报表并且不要改变不可变项目时,如果该项目是定义成相对Non-Volatile (Relative)的,数值0表示不改变数据,如果不可变项目是定义成绝对(Absolute)的,超出范围外的数值则表示不改变数据。 7 ② 0 第8章 USB接口HID设备 189 1 Volatile 0 Bit Field 1 Buffered Bytes 可变的:表示设备可以自己改变数值,并不是必须主机传送报表要求给设备来改变数值。例如设备控制面板可以由主机软件传送一个报表给设备,也可以由用户自己按设备上的实际按钮。 位字段:表示每一个位或是一个字节内的一组位可以代表一份数据。 缓冲字节:表示信息包含一个或多个字节,缓冲字节的报表大小必须是8。 保留 8 ① 9~31位 注: ①:该位不能应用到数组。

②:只应用于Output和Feature项目,对于Input项目该位保留。

(2)Collection和End Collection项目

所有的报表类型都可以使用Collection与 End Collection项目来将相关的Main类型项目组成群组。这两个项目分别用于打开和关闭集合。所有在Collection与End Collection项目之间的Main类型项目都是 Collection的一部分。

Collection有3种类型:Application、Physical与Logical,其项目的数据项的值分别为1、0和2。厂商也可以自己定义Collection类型,数据项的值为80h~FFh保留给厂商定义。End Collection项目无数据项。

Application Collection包含有共同用途的项目或执行单一功能的项目。例如键盘的开机描述符将键盘的按键与LED指示灯数据集合成一个Application Collection。所有的报表必须在一个Application Collection内。

Physical Collection包含在一个单一几何点上的数据项目,可以将每个位置的数据集合成一个 Physical Collection。在设备报告多个传感器的位置的时候,使用Physical Collection指明不同的数据来自不同的传感器。

Logical Collection形成一个数据结构,包含由 Collection所连结的不同类型的项目。例如数据缓冲区的内容以及缓冲区内字节数目的计数。

(3)Usage Page和Usage项目

Usage page项目的数据部分为1~2个字节,目前的定义全部都是一个字节。Usage Page定义了常用的设备功能,关于Usage Page(以及其他项目)的具体定义内容,可以查阅HID Usage tables(http://www.usb.org/developers/hidpage/#Class_Definition),下表是来自HID Usage tables的Usage Page定义。

Page ID 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 表8-6 Usage Page定义 Page Name Undefined Generic Desktop Controls Simulation Controls VR Controls Sport Controls Game Controls Generic Device Controls Keyboard/Keypad LEDs Button Ordinal Telephony Consumer Digitizer Reserved 190 计算机高级接口实践 0F PID Page 10 Unicode 11-13 Reserved 14 Alphanumeric Display 15-3f Reserved 40 Medical Instruments 41-7F Reserved 80-83 Monitor pages 84-87 Power pages 88-8B Reserved 8C Bar Code Scanner page 8D Scale page 8E Magnetic Stripe Reading (MSR) Devices 8F Reserved Point of Sale pages 90 Camera Control Page 91 Arcade Page 92-FEFF Reserved FF00-FFFF Vendor-defined

关于Usage Page的每一个有效定义项,都有一个相应的下一级定义,如Usage Page的数据项数值为1,则设备定义为Generic Desktop Controls,关于该类设备的具体功能可以在HID Usage Tables中查到具体的定义。下表是HID Usage Tables中对Generic Desktop Controls设备的功能定义。

表8-7 Generic Desktop Controls 用法定义 Usage ID 00 01 02 03 04 05 06 07 08 09 0A-2F 30 31 32 33 34 35 36 37 38 39 3A Usage Name Undefined Pointer Mouse Reserved Joystick Game Pad Keyboard Keypad Multi-axis Controller Tablet PC System Controls Reserved X Y Z Rx Ry Rz Slider Dial Wheel Hat switch Counted Buffer Usage Type CP CA CA CA CA CA CA CA DV DV DV DV DV DV DV DV DV DV CL 参阅HID Usage Tables中的相关章节 4.1 4.1 4.2 4.3 4.6

196 计算机高级接口实践

8.3.3 接口描述符

接口描述符的代码如下。

;========================================= ; Interface descriptor 接口描述符 ;========================================= InterfaceDescriptor0: DB 0x09 ; bLength = 9,该描述符长度 DB 0x04 ; bDescriptorType = 4,表明是接口描述符 DB 0x00 ; bInterfaceNumber = 0,此接口的识别标识符 DB 0x00 ; bAlternateSetting = 0,表示此接口无替代设置值 DB 0x01 ; bNumEndpoints = 1,本接口的端点数目,HID设备使用端点1 DB 0x03 ; bInterfaceClass = 3,表示该设备是HID类别 DB 0x01 ; bInterfaceSubClass = 1,表示支持启动接口 DB 0x01 ; bInterfaceProtocol = 1,表示支持键盘协议 DB 0x00 ; iInterface = 0,接口描述符说明字符串的索引值,0表示无字符串 8.3.4 HID描述符

HID描述符的代码如下。

;========================================= ; HID descriptor HID描述符 ;========================================= HIDDescriptor0: DB 0x09 ; bLength = 9,该描述符长度 DB 0x21 ; bDescriptorType = 21h,表明是HID描述符 DB 0x00, 0x01 ; bcdHID = 0100,HID规范版本为1.00 DB 0x00 ; bCountryCode = 0,硬件设备所在国家的国家代码,0表示未指明 DB 0x01 ; nNumDescriptors = 1,表示支持的描述符有1个,即一个报表描述符 DB 0x22 ; bDescriptorType = 22h,描述符类别,表示支持的描述符是报表描述符 DB 0x3F, 0x00 ; wDescriptorLength = 63,表示支持的报表描述符的长度 8.3.5 端点描述符

端点描述符的代码如下。

;========================================= ; EndPoint descriptor 端点描述符 ;========================================= EndpointDescriptor0: DB 0x07 ; bLength = 7,该描述符长度 DB 0x05 ; bDescriptorType = 5,表明是端点描述符 DB 0x81 ; bEndpointAddress = 1000 0001b,表示1号输入端点 DB 0X03 ; bmAttributes = 00000011b,表示中断类型端点 DB 0x08, 0x00 ; wMaxPacketSize = 8,端点发送和接收的最大包尺寸为8 DB 10 ; bInterval = 10,表示中断端点轮询时间间隔为10ms 8.3.6 字符串描述符

字符串描述符的代码如下。

第8章 USB接口HID设备 197

;========================================= ; String descriptor 字符串描述符

;========================================= StringDescriptor0: DB 0x04 ; bLength = 4,字符串描述符0的长度为4 DB 0x03 ; bDescriptorType = 3,表明是字符串描述符 DB 0x09, 0x00 ; wLANGID = 0009h,表明是英语 DB 0x0A ; bLength = 10,字符串描述符的长度为10 DB 0x03 ; bDescriptorType = 3,表明是字符串描述符 DB 0x41, 0x00, 0x43, 0x00, 0x4D, 0x00, 0x45, 0x00 ; bString = “ACME“,Unicode编码的字符串 DB 0x22 ; bLength = 34,字符串描述符的长度为34 DB 0x03 ; bDescriptorType = 3,表明是字符串描述符 DB 0x4C, 0x00, 0x6F, 0x00, 0x63, 0x00, 0x61, 0x00 DB 0x74, 0x00, 0x6F, 0x00, 0x72, 0x00, 0x20, 0x00 DB 0x4B, 0x00, 0x65, 0x00, 0x79, 0x00, 0x62, 0x00 DB 0x6F, 0x00, 0x61, 0x00, 0x72, 0x00, 0x64, 0x00 ; bString = “Locator Keyboard“,Unicode编码的字符串 DB 0x0E ; bLength = 14,字符串描述符的长度为14 DB 0x03 ; bDescriptorType = 3,表明是字符串描述符 DB 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x21, 0x00 DB 0x22, 0x00, 0x23, 0x00 ; bString = “ABC123“,Unicode编码的字符串

8.3.7 报表描述符

报表描述符的代码如下。

;========================================= ;HID Reports Descriptor 报表描述符

;========================================= DB 0x05, 1 ; Usage Page (1: Generic Desktop) DB 0x09, 6 ; Usage (6: Keyboard) 表示报表定义的是HID键盘 DB 0xA1, 1 ; Collection (1: Application) ====================集合开始 ; ; 以下定义了键盘的修饰键输入报表,共有8个键,组成一个字节 ; 用法见HID Usage Table中的第10节中的键盘用法定义 DB 0x05, 7 ; Usage page (7: Key Codes) DB 0x19, 224 ; Usage Minimum (224) DB 0x29, 231 ; Usage Maximum (231) DB 0x15, 0 ; Logical Minimum (0) DB 0x25, 1 ; Logical Maximum (1) DB 0x75, 1 ; Report Size (1) DB 0x95, 8 ; Report Count (8) DB 0x81, 2 ; Input (Data,Variable,Absolute) ; ; 以下定义了一个保留字节的输入报表 DB 0x95, 1 ; Report Count (1) DB 0x75, 8 ; Report Size (8), DB 0x81, 1 ; Input (Constant) = Reserved Byte ; ; 以下定义了键盘的LED指示灯输出报表项目,共有5个指示灯 ; 用法见HID Usage Table中的第11节中的LED用法定义 DB 0x95, 5 ; Report Count (5) DB 0x75, 1 ; Report Size (1)

198 计算机高级接口实践 DB 0x05, 8 ; Usage Page (Page# for LEDs) DB 0x19, 1 ; Usage Minimum (1) DB 0x29, 5 ; Usage Maximum (5) DB 0x91, 2 ; Output (Data, Variable, Absolute) ; ; 以下定义了3个填充位,与前面的5个LED指示灯数据组成一个完整的字节 DB 0x95, 1 ; Report Count (1) DB 0x75, 3 ; Report Size (3) DB 0x91, 1 ; Output (Constant) ; ; 以下定义了键盘的按键值输入报表项目,共6个字节,存放键编号(0~101) ; 用法见HID Usage Table中的第10节中的键盘用法定义 ; 这样的设计可以允许一次输入6个按键的键值 DB 0x95, 6 ; Report Count (6) DB 0x75, 8 ; Report Size (8) DB 0x15, 0 ; Logical Minimum (0) DB 0x25, 101 ; Logical Maximum (101) DB 0x05, 7 ; Usage Page (7: Key Codes) DB 0x19, 0 ; Usage Minimum (0) DB 0x29, 101 ; Usage Maximum (101) DB 0x81, 0 ; Input (Data, Array)

DB 0xC0 ; End_Collection ================================ 集合结束

通过上面的报表描述符的定义,确定了键盘的输入报表和输出报表的数据格式。其中输入报表共8个字节,输出报表只有1个字节。

键值6 字节7

键值5 字节6

键值4 键值3 键值2 字节3

键值1 保留 修饰键 字节0

字节5 字节4 字节2 字节1

图8-4 键盘的输入报表格式

7~5 4 3 2 1 0 字节0 Nnm Lock 指示灯 Caps Lock 指示灯 Scroll Lock 指示灯 Compose 指示灯 Kana 指示灯 常数,保留 图8-5 键盘的输出报表格式

第8章 USB接口HID设备 199

8.4 HID的特定请求

除了USB设备的11个标准请求外,HID规范另外还定义了6个HID特定控制请求。所有的HID设备都必须支持Get_Report请求,同时支持启动的设备必须支持Get_Protocol请求和Set_Protocol请求,其他的请求是可选择的。如果设备没有中断输出端点,此设备需要支持Get_Report请求来从主机读取数据。

在控制传输的设置阶段的数据包中的8个字节中的第一字节bmRequestType的编码含义参阅第6章中的USB标准请求。第2个字节bRequest定义请求的内容。wValue因请求的不同而不同。wIndex指明HID所在的接口。

表8-10 HID特定的请求 bmRequestType bRequest (值) 1 01 00001b 0 01 00001b 1 01 00001b 0 01 00001b 1 01 00001b 0 01 00001b Get_Report (1) Set_Report (9) Get_Idle (2) Set_Idle (10) Get_Protocol (3) Set_Protocol (11) wValue wIndex wLength 数据阶段 报表 报表 闲置时间 无 0: 启动协议 1: 报表协议 无 报表类型,报表ID 接口 报表长度 报表类型,报表ID 接口 报表长度 0,报表ID 接口 1 0 1 0 闲置时间,报表ID 接口 0 0: 启动协议 1: 报表协议 接口 接口 8.4.1 Get_Report请求

Get_Report的作用是启用主机使用控制传输,来从设备读取数据。

在使用时wValue字段的高字节是报表类型,1表示Input报表,2表示Output报表,3表示Feature报表。wValue的低字节是报表的Report ID,如果没有定义Report ID,该字节为设0。

在携带请求的控制传输的数据阶段,HID设备回传指定的报表内容。

HlD规范不建议使用该请求获得未经定时的数据,这样的数据建议使用中断输入管道获得。

该请求用来取得在主机初始化设备时的特征项目状态和其他信息。使用开机协议的主机可以使用此请求来获得按键或鼠标数据。

8.4.2 Set_Report请求

Set_Report请求的参数含义和Get_Report一样,但Set_Report请求的数据方向与Get_Report相反,在后面的数据阶段,主机传送报表到HID设备,这样的输出报表可以用于复位设备的控制,复位产生的效果取决于对应的控制的类型是相对(Reletive)的还是绝对(Absolute)的。

8.4.3 Set_Idle请求

Set_Idle请求的作用是静默一个在中断输入管道的特定的报表,直到一个发生一个相关的事件或过去了规定的时间,当数据从上一个报表后没有改变时,可以通过限制中断输入端点的报表频率来节省传输带宽。HID设备不是必需支持此请求。

wValue字段的高字节是设置的闲置时间,是报表之间的最大间隔时间。该字节为0表示闲置时间为无限长,在这种情况下,设备只有在报表数据有改变时才传送报表,否则

200 计算机高级接口实践

设备传回一个NAK。

wValue字段的低字节指示此请求应用的报表的Report ID。如果低字节是0,此请求应用到设备的所有输入报表。

闲置时间以4ms为单位,范围在4ms~1020ms之间。如果报表的数据自从上一次报表后有改变,或是接收到一个请求,设备会传送一个报表。

如果报表的数据没有改变,而且从上一次报表后过去的时间自尚未达到规定的闲置时间,设备会传回一个NAK。如果报表的数据没有改变,而且持续时间已经达到的闲置时间,设备会传送一个报表。

闲置时间设置为0表示无限长的闲置时间,设备只有在报表的数据有改变时才会传送一个报表,对于其他的中断输入请求则是传回NAK。

在检测HID设备时,Wndows的HID驱动程序会试图将闲置时间设置成0。如果HID设备不支持此请求,主机会收到传回的Stall。

8.4.4 Get_Idle请求

Get_Idle请求的作用是过的设备的当前闲置时间,在数据阶段,HID设备回传一个字节的闲置时间值。

8.4.5 Get_Protocol请求

Get_Protocol请求的作用是主机获取设备目前作用的是启动协议还是报表协议。 在数据阶段中设备回传的1个字节信息包中的数据值为0表示启动协议,为1表示报表协议。

启动设备必需支持该请求。

8.4.6 Set_Protocol请求

Set_Protocol的作用是主机指定设备使用启动协议或报表协议。

在数据阶段中主机传送的1个字节信息包中的数据值为0表示指定启动协议,为1表示指定报表协议。

启动设备必需支持该请求。

8.5 HID程序设计

HID设备是Windows系统提供了完善支持的一类,应用程序可以通过标准的API函数调用,实现与HID设备的通信。Windows系统提供了几千个API函数,作为应用程序与操作系统的接口,与HID相关的API函数被封装在hid.dll、setupapi.dll和kernal32.dll文件中。

8.5.1 HID访问使用的API函数

文件hid.dll中提供了很多个API,因为与HID设备通信有一定的复杂性。首先,在应用程序与HID传输数据之前,应用程序必须先识别该设备并且读取它的报表信息,这些动作需要调用多个API函数才可以实现。应用程序需要寻找连接到系统上的是哪些HID设备,然后读取每个设备的信息直到查找到所需的属性。如果是客户化的设备,应用程序可以寻找特定的厂商与产品ID,或者应用程序可以寻找特定类型的设备,例如键盘或鼠标。

本文来源:https://www.bwwdw.com/article/f1c6.html

Top