自定义HID设备HID报告描述符 [英] Custom HID device HID report descriptor

查看:412
本文介绍了自定义HID设备HID报告描述符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

生成HID描述符有点问题. 我想使用简单报表,其中ID1用于输入,ID2用于具有64字节数据的输出.

I have a bit of a problem with generating a HID descriptor. I want to use simple reports with ID1 for input and ID2 for output with 64 bytes of data.

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

I realized that despite RTFMing and googling I still do not have a clue about some fields in HID descriptor.

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

What is a hint or a manual where I can find the meaning of all descriptor fields? All I could find was examples for HID-mouse, joystick, and keyboard.

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

For example - REPORT_SIZE - is it size in bytes or in bits? And why is there also REPORT_COUNT? If I have 64 bytes in the report, must LOGICAL_MAXIMUM be 255 or 255*64?

我应该为每个报告写LOGICAL_MAX和MIN吗?

Should I write LOGICAL_MAX and MIN for every report or not?

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

Or maybe will this one (generated rather by guessing) suffice?

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
};

推荐答案

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

  1. All the official documentation is available on usb.org. To understand HID Report Descriptors you need to read some of the documents on the HID Information page. In particular, you should try to understand:

  • "HID 1.11的设备类定义"文档-描述了人机界面设备报告格式
  • "HID使用情况表1.12"文档-描述了许多使用情况页面的值以及这些页面中可以显示在报表描述符中的使用情况

话虽如此,但众所周知,该文档过于晦涩,将需要大量的精力来进行消化.

Having said that, the documentation is notoriously obtuse and will require considerable effort to digest.

REPORT_SIZE是报告的大小,以位为单位,而不是以字节为单位.将REPORT_SIZE视为字段的宽度(以位为单位),将REPORT_COUNT视为字段的数量(以该宽度为单位).在"HID 1.11的设备类定义"文档的第6.2.2.7节全局项"中对此进行了明确说明,如下所示:

REPORT_SIZE is the size of a report in bits not bytes. Think of REPORT_SIZE as the width of a field (in bits) and the REPORT_COUNT as the number of fields (of that width). This is made clear in the "Device Class Definition for HID 1.11" document, Section 6.2.2.7 "Global Items" as follows:

Global Item Tag     One-byte Prefix    Description
Report Size         0111 01 nn         Unsigned integer specifying the size of the report
                                       fields in bits. This allows the parser to build an
                                       item map for the report handler to use. For more
                                       information, see Section 8: Report Protocol.

  • 作为指导,一个合理的(即我尚未测试过的)报告描述符描述一个64字节的输入缓冲区(发送给REPORT_ID为0x01的主机)和一个64字节的输出缓冲区(来自具有REPORT_ID为0x02的主机)可以如下:

  • As a guide, a reasonable (i.e I haven't tested it) Report Descriptor that describes a 64-byte input buffer (to the host with a REPORT_ID of 0x01) and a 64-byte output buffer (from the host with a REPORT_ID of 0x02) could be as follows:

      0x06, 0x00, 0xFF,            // (GLOBAL) USAGE_PAGE         0xFF00 Vendor-defined 
      0xA1, 0x01,                  // (MAIN)   COLLECTION         0x01 Application (Usage=0x0: Page=, Usage=, Type=) <-- Warning: USAGE type should be CA (Application)
      0x15, 0x00,                  //   (GLOBAL) LOGICAL_MINIMUM    0x00 (0) <-- Redundant: LOGICAL_MINIMUM is already 0
      0x26, 0xFF, 0x00,            //   (GLOBAL) LOGICAL_MAXIMUM    0x00FF (255) 
      0x75, 0x08,                  //   (GLOBAL) REPORT_SIZE        0x08 (8) Number of bits per field 
      0x85, 0x01,                  //   (GLOBAL) REPORT_ID          0x01 (1) 
      0x95, 0x40,                  //   (GLOBAL) REPORT_COUNT       0x40 (64) Number of fields 
      0x09, 0x01,                  //   (LOCAL)  USAGE              0xFF000001  
      0x81, 0x02,                  //   (MAIN)   INPUT              0x00000002 (64 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
      0x85, 0x02,                  //   (GLOBAL) REPORT_ID          0x02 (2) 
      0x09, 0x01,                  //   (LOCAL)  USAGE              0xFF000001  
      0x91, 0x02,                  //   (MAIN)   OUTPUT             0x00000002 (64 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
      0xC0,                        // (MAIN)   END_COLLECTION     Application
    

    对应于以下C语言结构定义:

    Which corresponds to the following C-language structure definitions:

    //--------------------------------------------------------------------------------
    // Vendor-defined inputReport 01 (Device --> Host)
    //--------------------------------------------------------------------------------
    
    typedef struct
    {
      uint8_t  reportId;                                 // Report ID = 0x01 (1)
      uint8_t  VEN_VendorDefined0001[64];                // FF00 0001  Value = 0 to 255
    } inputReport01_t;
    
    //--------------------------------------------------------------------------------
    // Vendor-defined outputReport 02 (Device <-- Host)
    //--------------------------------------------------------------------------------
    
    typedef struct
    {
      uint8_t  reportId;                                 // Report ID = 0x02 (2)
      uint8_t  VEN_VendorDefined0001[64];                // FF00 0001  Value = 0 to 255
    } outputReport02_t;
    

  • 是否应为每个报告指定LOGICAL_MINIMUM和LOGICAL_MAXIMUM?否

  • Should you specify LOGICAL_MINIMUM and LOGICAL_MAXIMUM for each report? No.

    某些项是GLOBAL(这意味着,按顺序解析报表描述符,它们的值一直保留到被另一个GLOBAL项显式更改为止),而其他项是LOCAL(这意味着每当MAIN都将其值重置为默认值)遇到项目). LOGICAL_MINIMUM和LOGICAL_MAXIMUM都是GLOBAL项目,因此,如果您想更改值,则只需重新指定它们的值即可.我认为,如果商品的正式名称以GLOBAL_,LOCAL_和MAIN_作为前缀,则规范会更加清晰,但不幸的是,我们所有人都必须遵守规范.

    Some items are GLOBAL (which means that, as the report descriptor is parsed sequentially, their values remain until they are explicitly changed by another GLOBAL item) and others are LOCAL (which means that their values are reset to defaults whenever a MAIN item is encountered). Both LOGICAL_MINIMUM and LOGICAL_MAXIMUM are GLOBAL items, so you only need to re-specify their values if you want the value to change. In my opinion, the specification would have been clearer if the official names for items were prefixed by GLOBAL_, LOCAL_ and MAIN_ but unfortunately we all have to live with the spec as it stands.

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

    The above example was decoded using a free tool on SourceForge called hidrdd

    这篇关于自定义HID设备HID报告描述符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆