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

Usb 自定义HID设备HID报告描述符,usb,hid,Usb,Hid,我在生成HID描述符时有点问题。 我想使用简单的报告,ID1用于输入,ID2用于输出64字节的数据 我意识到,尽管使用RTFMing和谷歌搜索,我仍然对HID描述符中的某些字段一无所知 什么是可以找到所有描述符字段含义的提示或手册?我所能找到的只是HID鼠标、操纵杆和键盘的例子 例如-报告大小-大小是以字节还是以位为单位?为什么还有报告计数? 如果报告中有64个字节,逻辑_的最大值必须是255或255*64吗 我是否应该为每个报告编写逻辑_MAX和MIN 或者这一个(通过猜测产生的)就足够了 所

我在生成HID描述符时有点问题。 我想使用简单的报告,ID1用于输入,ID2用于输出64字节的数据

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

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

例如-报告大小-大小是以字节还是以位为单位?为什么还有报告计数? 如果报告中有64个字节,逻辑_的最大值必须是255或255*64吗

我是否应该为每个报告编写逻辑_MAX和MIN

或者这一个(通过猜测产生的)就足够了

  • 所有官方文件均可在usb.org上获得。要理解HID报告描述符,您需要阅读页面上的一些文档。特别是,您应该努力理解:

    • “HID 1.11设备类定义”文档-描述人机界面设备报告格式
    • “HID使用情况表1.12”文档-描述了许多使用情况页面的值以及这些页面中可能出现在报告描述符中的使用情况
    话虽如此,文件是出了名的迟钝,将需要相当大的努力来消化

  • 报表大小是报表的大小,以位而不是字节为单位。将REPORT_SIZE视为字段的宽度(以位为单位),REPORT_计数为字段的数量(以该宽度为单位)。“HID 1.11设备类别定义”文件第6.2.2.7节“全局项”中对此作了明确说明,如下所示:

    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.
    
      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
    
  • 作为指导,描述64字节输入缓冲区(到报表ID为0x01的主机)和64字节输出缓冲区(从报表ID为0x02的主机)的合理(即我尚未测试)报表描述符可以如下所示:

    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.
    
      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
    
    0x06、0x00、0xFF、//(全局)用法\u第0xFF00页供应商定义
    
    0xA1,0x01,//(主)集合0x01应用程序(用法=0x0:Page=,用法=,Type=)我的自定义HID设备已被Windows7检测到(通过猜测和从示例中窃取构建):

    但我不确定它是否能正常工作。我们将看到。

    这里有一个指向(或“手册”)的链接,供您阅读

    为了回答您的一些问题,
    REPORT\u SIZE
    以位为单位指定,并且
    REPORT\u COUNT
    可用于指定使用指定属性报告的“使用次数”。例如,您可以设置
    X
    Y
    用法的属性,并将
    报告计数指定为2(一个用于X,一个用于Y),然后指定
    输入将这些用法添加到报告中。然后继续描述其他用法


    另外,不要忘记将用法与字节对齐。由于
    REPORT\u COUNT
    是以位为单位指定的,因此很容易忘记使用字节对齐。因此,如果一次使用仅为1位,则需要指定该字节中有7位未被使用,然后再移动到下一次使用,如果它需要超过7位。

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

    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)
    在窗口方面,我使用。HID报告通常以报告ID作为前缀——在HIDLibrary中,使用
    HidReport.ReportID
    字段设置/获取值。在电路板端,请记住报告的第一个字节将是报告ID。

    HID报告描述符是键值对。要理解它们,请阅读HID规范,第6章在这种情况下很有帮助。您从哪里找到这些值的来源,以及它如何影响描述符?如果我们改变它们:

    Key   Value
    --------------------------------------
    0x85, 0x02,     //   REPORT_ID (2)
    0x75, 0x08,     //   REPORT_SIZE (8)
    0x95, 0x40,     //   REPORT_COUNT (64)
    
    @诀窍:

    如果您在理解REPORT_COUNT(0x95)和REPORT_SIZE(0x75)时遇到问题,那么您可以将其想象为一个二维数组

    其中4表示要发送的报告总数,8表示每个报告的大小

    就是

    struct报告
    {
    uint8报告1;
    uint8报告2;
    uint8报告3;
    uint8报告4;
    };
    
    我知道您说过您需要RTFM,但也要求提供手册-您是否检查了第6.2.2节中关于报告描述符的内容?报告大小以字节为单位。Report count是您支持的报告数。第5.8节描述了逻辑最小值和最大值。如果你想要一些不太“规范”-y的东西,那么看看。@Preston,事实上,是的,我有。我所能看到的只是一些字段的描述。使用、收集、输入、输出。还有一个HID鼠标的例子。这很有用,但还远远不够。如果report count是报告数-为什么一个HID鼠标描述符中有三个报告?谢谢你的书,我会查的!报告大小以位而不是字节为单位。答案是正确的,谢谢。不幸的是,仅仅通过复制描述符并没有起作用,但这仍然很有帮助。请选择您推荐的
    hidrdd
    。@quantum231是这样做的。@Notflip我认为更容易找到实际的hid鼠标描述符。例如,这个文档包含它谢谢你的回答,我找到了一个工作描述符!现在我仍在尝试向它发送数据。谢谢Re“官方USB文档为ra
    Key   Value
    --------------------------------------
    0x85, 0x02,     //   REPORT_ID (2)
    0x75, 0x08,     //   REPORT_SIZE (8)
    0x95, 0x40,     //   REPORT_COUNT (64)
    
    Array[count][size] = Array[4][8] /* Values are in [Bytes][bit] */