首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自定义HID设备HID报告描述符

自定义HID设备HID报告描述符
EN

Stack Overflow用户
提问于 2014-02-06 23:26:34
回答 5查看 42.8K关注 0票数 16

我在生成HID描述符时遇到了一点问题。我想使用简单的报表,其中ID1用于输入,ID2用于输出,数据为64字节。

我意识到,尽管有RTFMing和谷歌搜索,我仍然对HID描述符中的一些字段一无所知。

我可以找到所有描述符字段的含义的提示或手册是什么?我所能找到的只有HID鼠标、操纵杆和键盘的例子。

例如- REPORT_SIZE -它的大小是以字节还是以位为单位?为什么还有REPORT_COUNT?如果报告中有64个字节,LOGICAL_MAXIMUM必须是255或255*64吗?

我是否应该为每个报告编写LOGICAL_MAX和MIN?

或者,这个(通过猜测生成)就足够了吗?

代码语言:javascript
复制
char ReportDescriptor[39] = {
    0x05, 0x01,         // USAGE_PAGE (Generic Desktop)
    0x09, 0x00,         // USAGE (Undefined)
    0xa1, 0x01,         // COLLECTION (Application)
    0x85, 0x01,         //   REPORT_ID (1)
    0x09, 0x00,         //   USAGE (Undefined)
    0x15, 0x00,         //   LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,   //   LOGICAL_MAXIMUM (255)
    0x75, 0x40,         //   REPORT_SIZE (64)
    0x96, 0x00, 0x02,   //   REPORT_COUNT (512)
    0x81, 0x82,         //   INPUT (Data,Var,Abs,Vol)
    0x85, 0x02,         //   REPORT_ID (2)
    0x09, 0x00,         //   USAGE (Undefined)
    0x15, 0x00,         //   LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,   //   LOGICAL_MAXIMUM (255)
    0x75, 0x40,         //   REPORT_SIZE (64)
    0x96, 0x00, 0x02,   //   REPORT_COUNT (512)
    0x91, 0x82,         //   OUTPUT (Data,Var,Abs,Vol)
    0xc0                // END_COLLECTION
};
EN

回答 5

Stack Overflow用户

发布于 2014-02-10 19:44:45

  1. 所有官方文档都可以在usb.org上找到。要理解HID报告描述符,您需要阅读HID Information页面上的一些文档。特别是,您应该尝试理解:

代码语言:javascript
复制
- The "Device Class Definition for HID 1.11" document - which describes the Human Interface Device report format
- The "HID Usage Tables 1.12" document - which describes the values of many Usage Pages and Usages within those pages that can appear in a Report Descriptor

话虽如此,这些文档是出了名的迟钝,需要相当大的努力来消化。

  1. REPORT_SIZE是报告的大小,以位为单位,而不是字节。可以将REPORT_SIZE视为字段的宽度(以位为单位),将REPORT_COUNT视为字段的数量(具有该宽度)。这在“HID 1.11的设备类定义”文档的6.2.2.7节“全局项目”中作了明确说明,如下所示:

全局项目标记单字节前缀描述报告大小0111 01 nn无符号整数指定报告字段的大小(以位为单位)。这允许解析器为报表处理程序构建要使用的项映射。有关详细信息,请参阅第8节:报告协议。

  • 作为指南,描述64字节输入缓冲区(到REPORT_ID为0x01的主机)和64字节输出缓冲区(来自REPORT_ID为0x02的主机)的合理(即我尚未测试)报告描述符可能如下所示:

0x06,0x00,0xFF,// (全局) USAGE_PAGE 0xFF00供应商定义的0xA1,0x01,// (主)集合0x01应用程序(Usage=0x0: Page=,Usage=,Type=) <--警告:使用类型应该是CA (应用程序) 0x15,0x00,// (全局) LOGICAL_MINIMUM 0x00 (0) <--冗余: LOGICAL_MINIMUM已经是0 0x26,0xFF,0x00,// (全局) LOGICAL_MAXIMUM 0x00FF (255) 0x75,0x08,// (全局) REPORT_SIZE 0x08 (8)每个字段的位数0x85,0x01,// (全局) REPORT_ID 0x01 (1) 0x95,0x40,// (全局) REPORT_COUNT 0x40 (64)字段的数量0x09,0x01,// (本地)用法0xFF000001 0x81,0x02,// (主)输入0x00000002 (64个字段x 8位) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 0x85,0x02,// (全局) REPORT_ID 0x02 (2) 0x09,0x01,// (本地)用法0xFF000001 0x91,0x02,// (主)输出0x00000002 (64个字段x 8位) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 0xC0,// (主) END_COLLECTION应用程序

它对应于下面的C语言结构定义:

//-------------------------------------------------------------------------------- //供应商定义的inputReport 01 (设备-->主机)//类型定义结构{ uint8_t reportId;// Report ID = 0x01 (1) uint8_t VEN_VendorDefined000164;// FF00 0001 Value =0到255 } inputReport01_t;//-------------------------------------------------------------------------------- //供应商定义的outputReport 02 (设备<--主机)//类型定义结构{ uint8_t reportId;//报告ID = 0x02 (2) uint8_t VEN_VendorDefined000164;// FF00 0001 VEN_VendorDefined000164=0到255 } outputReport02_t;

  • Should您是否为每个报告指定了LOGICAL_MINIMUM和LOGICAL_MAXIMUM?不是的。

有些项是全局的(这意味着,在按顺序分析报告描述符时,它们的值将一直保留,直到被另一个全局项显式更改),而其他项则是局部的(这意味着每当遇到主项时,它们的值都会被重置为默认值)。LOGICAL_MINIMUM和LOGICAL_MAXIMUM都是全局项,因此如果希望更改值,只需重新指定它们的值。在我看来,如果项目的正式名称以GLOBAL_,LOCAL_和MAIN_为前缀,那么规范会更清晰,但不幸的是,我们都必须接受现有的规范。

  • 上面的示例是使用SourceForge上的一个名为hidrdd

的免费工具解码的

票数 26
EN

Stack Overflow用户

发布于 2017-10-14 03:37:24

正如@aja上面所说的,官方的USB文档相当迟钝。我创建了这个模板(主要是通过这个页面的帮助),作为与自定义电路板通信的简单起点。HID代码旨在替换虚拟COM端口协议。使用HID的最大优势是不需要驱动程序。

代码语言:javascript
复制
uint8_t CUSTOM_HID_ReportDesc[REPORT_DESC_SIZE] =
{
   0x06, 0x00, 0xFF,    // Global  Usage page = 0xFF00 (Vendor-defined pages are in the range 0xFF00 through 0xFFFF)
   0x09, 0x01,          // Local   Usage (vendor usage 1)
   0xA1, 0x01,          // Main    Collection (application) begin
   0x15, 0x00,          // Global  Logical minimum (0) applies to each byte
   0x26, 0xFF, 0x00,    // Global  Logical maximum (255)
   0x75, 0x08,          // Global  Report Size (8 bits)

   // 14 bytes | Output message 1 (sent from host to device)
   0x85,  1,            // Global  Report ID (cannot be 0)
   0x98, 64,            // Global  Report Count (number of Report Size fields, in this case 64 bytes)
   0x19, 0x01,          // Local   Usage Minimum (each Report Count must be associated with a Usage)
   0x19, 0x40,          // Local   Usage Maximum
   0x91, 0x02,          // Main    Output (data, array, absolute)

   // 24 bytes | Input message 1 (sent from device to host)
   0x85,  1,            // Global  Report ID (cannot be 0)
   0x98, 64,            // Global  Report Count (number of Report Size fields)
   0x19, 0x01,          // Local   Usage Minimum (each Report Count must be associated with a Usage)
   0x19, 0x40,          // Local   Usage Maximum
   0x81, 0x02,          // Main    Input (data, array, absolute)

   // 34 bytes | Output message 2 (sent from host to device)
   0x85,  2,            // Global  Report ID (cannot be 0)
   0x98, 12,            // Global  Report Count (number of Report Size fields)
   0x19, 0x01,          // Local   Usage Minimum (each Report Count must be associated with a Usage)
   0x19, 0x40,          // Local   Usage Maximum
   0x91, 0x02,          // Main    Output (data, array, absolute)

   // 44 bytes | Input message 2 (sent from device to host)
   0x85,  2,            // Global  Report ID (cannot be 0)
   0x98, 57,            // Global  Report Count (number of Report Size fields)
   0x19, 0x01,          // Local   Usage Minimum (each Report Count must be associated with a Usage)
   0x19, 0x40,          // Local   Usage Maximum
   0x81, 0x02,          // Main    Input (data, array, absolute)

   // 54 bytes | End (add one byte)
   0xC0                 // Main    Collection (application) end
}

需要注意的几件事:

  • 可以很容易地添加更多的输入/输出对:只需给它们另一个报告ID。每个消息定义由10个字节组成,因此很容易相加。
  • 我们跟踪描述符中的字节数,以便可以计算数组的大小(#define REPORT_DESC_SIZE (55)).

在Windows端,我使用Mike O'Brien's HIDLibrary。HID报告通常以报告ID作为前缀--在HIDLibrary中,使用HidReport.ReportID字段设置/获取该值。在电路板方面,请记住报告的第一个字节将是报告ID。

票数 8
EN

Stack Overflow用户

发布于 2014-02-18 21:21:23

我已经让我的自定义HID设备被Windows 7检测到了(通过猜测构建并从示例中窃取):

代码语言:javascript
复制
{
    0x05, 0x01,         // USAGE_PAGE (Generic Desktop)
    0x09, 0x00,         // USAGE (Undefined)
    0xa1, 0x01,         // COLLECTION (Application)
    0x15, 0x00,         //   LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,   //   LOGICAL_MAXIMUM (255)
    0x85, 0x01,         //   REPORT_ID (1)
    0x75, 0x08,         //   REPORT_SIZE (8)
    0x95, 0x40,         //   REPORT_COUNT (64)
    0x09, 0x00,         //   USAGE (Undefined)
    0x81, 0x82,         //   INPUT (Data,Var,Abs,Vol) - to the host
    0x85, 0x02,         //   REPORT_ID (2)
    0x75, 0x08,         //   REPORT_SIZE (8)
    0x95, 0x40,         //   REPORT_COUNT (64)
    0x09, 0x00,         //   USAGE (Undefined)
    0x91, 0x82,         //   OUTPUT (Data,Var,Abs,Vol) - from the host
    0xc0                // END_COLLECTION
}; /* CustomHID_ReportDescriptor */

不过,我不确定它是否能正常工作。我们将拭目以待。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21606991

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档