USB-HID一些笔记

HID(Human Interface Deviece)协议是USB协议中的一个子协议。指的是直接与人进行交互的设备。

一、简述一些概念

1.0 USB设备描述符

USB是个通用的总线,硬件端口是统一的,而USB设备却有很种,为了区分这些不同的设备,就得要用到不同设备各自的描述符。

1.1USB标准描述符

USB设备的信息存储在USB设备的固件中,当USB设备接入PC机启动后,主机会通过USB的标准请求,对存储在USB设备的固件信息进行读取分析。

USB有5种标准设备描述符,分别是:设备描述符、配置描述符、字符串描述符、接口描述符、端点描述符。

另外还有:HID描述符、报告描述符等各个类特有的描述符。

更详细的内容请查找USB协议的相关资料。

1.2HID描述符

由于USB HID设备的接口中标识了设备类型,但同一种设备类型因为厂商或实现机制的原因,数据格式不统一,所以虽然是同一种设备,但固件上报的数据格式甚至长度可能五花八门,那么通过什么方式来实现使USB主机端识别并解析这些数据呢?答案就是报告描述符。

USB HID描述符包括两种报表描述符,分别为物理描述符集合和报告描术符,也叫报表描述符。

  • 物理描述符集合是可选的描述符,提供用于激活设备控件的人体一个或多个部分的信息。
  • 报告描述符用于描述符USB HID设备上报的数据信息格式。

二、HID报告描述符/报表描述符

报表描述符用于描述USB_HID设备与主机之间数据交互的格式。根据数据的传输方向,分为输入报告和输出报告。

USB HID设备与主机传输的是数据,这些原始的数据就像内存里的数据一样,如果没有人告诉我们这些字节干什么的,也许我们永远也不知道的。USB报表描述符的功能就是用于描述这些报告数据格式。当主机或设备收到报告数据后,会根据报告描述符的内容解析并理解这些数据的含义

2.0输出报告

输出报告主要是由主机给HID设备发送数据,例如键盘上的LED灯的开关命令。在我的开发里面,输出报告使用的比较少,这里不加以描述。

2.1输入报告

输入报告主要是由HID设备发送给主机数据的报告,大部分HID设备主要实现的也是输入报告。例如鼠标的点击,移动,滚轮等操作。都是发送的输入报告。

2.2报表描述符的格式

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

HID的报表描述符并不像USB设备描述符一样,包含描述符的长度和描述符类型的信息。HID描述符是由一个个项目(item)组成。每一个项目具有其项目的信息。

HID定义了两种项目,一种是长项目,另一种是短项目。报告描述符里面的长项目一般不使用,一般短项目使用较多。这里就只介绍短项目。

2.2.0长项目(long item)

hid协议 android hid协议是什么协议_描述符

长项目可以携带更多的数据,当第一个字节为上图中的特定值时表明该项目是一个长项目。

hid协议 android hid协议是什么协议_描述符_02

2.2.1短项目(short item)

hid协议 android hid协议是什么协议_hid协议 android_03

  • bSize为0、1、2、3时Data部分的字节数分别为0、1、2、4个字节。
    0 = 0 bytes
    1 = 1 bytes
    2 = 2 bytes
    3 = 4 bytes
  • bType为0、1、2时分别为Main、Global和Local类型。
    0 = Main
    1 = Global
    2 = Local
    3 = Reserved
  • bTag:表示该项目的功能。
2.2.2三个项目类型(Main Item、Global Item、Local Item)

一些常用的项目类型,功能用法

hid协议 android hid协议是什么协议_hid协议 android_04

主项目(Main Item)

主项目其有5个,分别为Input,Output,Feature,Collection和End Collection.

Input、Outpot和Feature项目

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项目。

Input、Outpot和Feature项目,这3个项目用来定义报表中的数据字段。

hid协议 android hid协议是什么协议_单片机_05

Collection和End Collection项目

Collection共有四种,分别为Physical,Application,Logical和Vendoer Defined.

所有的报表类型都可以使用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所连结的不同类型的项目。例如数据缓冲区的内容以及缓冲区内字节数目的计数。

hid协议 android hid协议是什么协议_c语言_06

全局项目(Global Item)

全局项目主要用来选择用途页(Usage Page),定义数据域的长度(Report Count)、数量(Report Size)、报告ID(ReportId)等。

全局项目描述对后续的所有项目有效,除非遇到有新的全局项目。

常见的全局项目有:

  • Usage Page(用途页)
  • Logical Minimum(逻辑最小值)
  • Logical Maxinum(逻辑最大值)
  • Physical Minimum(物理最小值)
  • Physical Maximum(物理最大值)
  • Report Size:数据域大小,表示每个数据域有多少位
  • Report Count:数据域有多少个数据域。
  • ReportId:报告ID
局部项目(local Item)

局部项目用于定义数据的控制特性,如该数据域的用途,用途的最大值,用途的最小值等。

局部项目只在局部有效,遇到一个主项目后,它的失效。

常见的局部数据项目有:

  • Usage :用途
  • Usage Minmum:用途的最小值
  • Usage Maxmum:用途的最大值。

三、下面是鼠标的HID设备描述符举例

0x05, 0x01, // Usage Page (Generic Desktop Ctrls)   全局项目
0x09, 0x02, // Usage (Mouse)   局部项目
0xA1, 0x01, // Collection (Application)主项目
0x85, 0x04, //   Report ID (4)
0x09, 0x01, //   Usage (Pointer)   局部项目
0xA1, 0x00, //   Collection (Physical)   主项目
0x95, 0x03, //     Report Count (3) 全局项目 ->>>数量
0x75, 0x01, //     Report Size (1) 全局项目 ->>>位数 1位(bit)
0x05, 0x09, //     Usage Page (Button)   全局项目->>>定义用法(按键)
0x19, 0x01, //     Usage Minimum (0x01)   局部项目->>>使用最大值
0x29, 0x03, //     Usage Maximum (0x03)   局部项目->>>使用最小值
0x15, 0x00, //     Logical Minimum (0)   全局项目->>>逻辑最小值
0x25, 0x01, //     Logical Maximum (1)   全局项目->>>逻辑最大值
0x81, 0x02, //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)主项目->>>设置位输入项目
0x95, 0x01, //     Report Count (1) 全局项目->>>数量
0x75, 0x05, //     Report Size (5) 全局项目->>>位数
0x81, 0x03, //     Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)主项目->>>设置位输入项目 (Const常量不变量)填充上面Report Size 补足一个字节
0x95, 0x03, //     Report Count (3) 全局项目->>>数量
0x75, 0x08, //     Report Size (8) 全局项目->>>位数8位(bit)
0x05, 0x01, //     Usage Page (Generic Desktop Ctrls)全局项目
0x09, 0x30, //     Usage (X)局部项目
0x09, 0x31, //     Usage (Y)局部项目
0x09, 0x38, //     Usage (Wheel)局部项目
0x15, 0x81, //     Logical Minimum (-127)  全局项目
0x25, 0x7F, //     Logical Maximum (127) 全局项目
0x81, 0x06, //     Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)主项目
0xC0,       //   End Collection 主项目

发送的数据

hid协议 android hid协议是什么协议_c语言_07

一些比较好的网上资料,和一些比较好的学习网站

[USB中文网]( USB中文网 - USB技术开发交流 这个里面的的资料是比较全的,不止有USB_HID的协议,还有很多USB的其他资料。

USB_HID协议基础,这是一个博客,是一个比较厉害的博主写的对USB_HID的一个介绍,可以了解一下。