首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >HID USB控制传输(Windows)

HID USB控制传输(Windows)
EN

Stack Overflow用户
提问于 2017-12-20 08:57:47
回答 1查看 1.7K关注 0票数 0

最近,我开始学习如何在Windows 10上与HID设备通信。

但我有几个问题。

根据窗口的文档,HidD_SetOutputReport必须将ReportBuffer参数的第一个字节设置为报表ID或0x00

由于我的设备的HID报表描述符已经声明了一些报表id,所以当我使用HidD_setoutputreport而不是0x00时,我必须设置报表id

当我使用报告id 0x80作为buf[0]时,ex: 0x80 0x02 0x00 .0x00 (我的Capabilities.OutputReportByteLength是64)

我的代码是ret = HidD_SetOutputReport(handle->device_handle, buf2, 65)

但是我总是这样发送数据(在巴士猎犬上):

64出80 02 00 00 00 .4.1.0 00 00 00 .4.1.16 00 00 00 .4.1.32 00 00 00 .4.1.48

我认为它应该发送buf[1] to buf[64]而不是buf[0] to buf[63],所以我尝试了ret = HidD_SetOutputReport(handle->device_handle, buf2, 64),但是结果是一样的。

下面是输入和输出的HID报告描述符:

使用页(通用桌面) 05 01 逻辑最小值(0) 15 00 使用(欢乐棒) 09 04 收集(应用) A1 01 报告ID (48) 85 30 使用页(通用桌面) 05 01 使用页(按钮) 05 09 最低使用量(按钮1) 19 01 使用上限(按钮10) 290A 逻辑最小值(0) 15 00 逻辑最大值(1) 25 01 报告大小(1) 75 01 报告计数(10) 950A 单位指数(0) 55 00 单位(无) 65 000 输入(数据,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02 使用页(按钮) 05 09 最低使用量(按钮11) 19 0B 最大使用量(按钮14) 290E 逻辑最小值(0) 15 00 逻辑最大值(1) 25 01 报告大小(1) 75 01 报告清点(4) 95 04 输入(数据,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02 报告大小(1) 75 01 报告计数(2) 95 02 输入(Cnst,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 03 用法(一般桌面:指针) 0B 01 0001 00 集合(物理) A1 00 使用(通用桌面:x) 0B 30 00 01 00使用(通用桌面:y) 0B 31 00 01 00使用(通用桌面:Z) 32 00 01 00使用(通用桌面:Rz) 0B 35 00 01 00逻辑最小(0) 15 00逻辑最大值(65535) 27 FF FF 00报告大小(16) 75 10报告计数(4) 95 04输入(数据,Var,Abs,NWrp,Lin,Pref,NNul,( Bit) 81 02 端集C0 使用(通用桌面:帽子开关) 0B 39 0001 00 逻辑最小值(0) 15 00 逻辑最大值(7) 25 07 物理最小值(0) 35 00 物理最大值(315) 46 3B 01 单元(英罗特:学位) 65 14 报告大小(4) 75 04 报告计数(1) 95 01 输入(数据,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02 使用页(按钮) 05 09 最低使用量(按钮15) 19 0 F 最高使用量(按钮18) 29 12 逻辑最小值(0) 15 00 逻辑最大值(1) 25 01 报告大小(1) 75 01 报告清点(4) 95 04 输入(数据,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02 报告大小(8) 75 08 报告计数(52) 95 34 输入(Cnst,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 03 使用页(卖方定义1) 06 00 FF 报告ID (33) 85 21 使用(卖方定义1) 09 01 报告大小(8) 75 08 报告计数(63) 953 F 输入(Cnst,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 03 报告ID (129) 85 81 使用(卖方定义2) 09 02 报告大小(8) 75 08 报告计数(63) 953 F 输入(Cnst,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 03 报告ID (1) 85 01 使用(卖方定义3) 09 03 报告大小(8) 75 08 报告计数(63) 953 F 输出(Cnst,Var,Abs,NWrp,Lin,Pref,NNul,Vol.BIT) 91 83 报告ID (16) 85 10 使用(卖方定义4) 09 04 报告大小(8) 75 08 报告计数(63) 953 F 输出(Cnst,Var,Abs,NWrp,Lin,Pref,NNul,Vol.BIT) 91 83 报告ID (128) 85 80 使用(供应商定义5) 09 05 报告大小(8) 75 08 报告计数(63) 953 F 输出(Cnst,Var,Abs,NWrp,Lin,Pref,NNul,Vol.BIT) 91 83 报告ID (130) 85 82 使用(卖方定义6) 09 06 报告大小(8) 75 08 报告计数(63) 953 F 输出(Cnst,Var,Abs,NWrp,Lin,Pref,NNul,Vol.BIT) 91 83 端集C0

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-12-22 07:34:12

我不能对Windows进行评论(我从未使用过它),但我知道如果您在HID报告描述符中指定了报表id,那么报表id将占据数据包的第一个字节,而数据包的其余部分是您的有效负载,否则您的数据包都是有效负载,并且不会发送REPORT_ID。在您的示例中,RD指定了一个REPORT_ID和63个字节的有效载荷,因此我将指定一个长度为64,并将REPORT_ID放在第一个字节中。 报告id被传送到端点,以便它知道如何解释每个报告。

我已经检查了您的报告描述符,我可以建议一些可能减少未来悲伤的可能性的调整。

  • 从输入报告中移除pad的52字节.它只会被主机忽略,所以不需要从你的设备发送它。
  • 使用较短的使用代码来减小报表描述符的大小。如果您的设备内存不足,这一点可能很重要。
  • 在不需要时重置物理单位。如果您不这样做,那么物理单位适用于所有后续的项目-这可能是不合适的(例如,一个开关的长度(英寸))。我通过使用PUSH保存全局变量并在稍后方便地恢复它们来实现这一点。
  • 在输出报告中指定数据(非常量)。我真的不确定这是否有什么区别,但你永远不会知道,未来的一些USB驱动程序可能会选择在发送会导致痛苦的数据包之前将任何常量字段设置为空。

完成上述操作后,报表描述符大小从203个字节减少到133个字节:

代码语言:javascript
复制
//--------------------------------------------------------------------------------
// Report descriptor data in hex (length 133 bytes)
//--------------------------------------------------------------------------------


// 05011409 04A10185 30050925 017501A4 1901290A 950A8102 190B290E 95048102
// 95028103 05010901 A0093009 31093209 3527FFFF 00007510 95048102 C0093925
// 0734463B 01651475 04950181 02B4190F 29129504 810226FF 00750895 3F0600FF
// 85210901 81028581 09028102 85010903 91828510 09049182 85800905 91828582
// 09069182 C0      


//--------------------------------------------------------------------------------
// Decoded Application Collection
//--------------------------------------------------------------------------------

/*
05 01        (GLOBAL) USAGE_PAGE         0x0001 Generic Desktop Page 
14           (GLOBAL) LOGICAL_MINIMUM    (0) <-- Redundant: LOGICAL_MINIMUM is already 0 
09 04        (LOCAL)  USAGE              0x00010004 Joystick (CA=Application Collection) 
A1 01        (MAIN)   COLLECTION         0x00000001 Application (Usage=0x00010004: Page=Generic Desktop Page, Usage=Joystick, Type=CA)
85 30          (GLOBAL) REPORT_ID          0x30 (48) '0' 
05 09          (GLOBAL) USAGE_PAGE         0x0009 Button Page 
25 01          (GLOBAL) LOGICAL_MAXIMUM    0x01 (1)  
75 01          (GLOBAL) REPORT_SIZE        0x01 (1) Number of bits per field  
A4             (GLOBAL) PUSH               USAGE_PAGE=0x0009 LOGICAL(MIN=0,MAX=1) PHYSICAL(MIN=0,MAX=0) UNIT(0x0,EXP=0) REPORT(ID=0x30,SIZE=1,COUNT=0)
19 01          (LOCAL)  USAGE_MINIMUM      0x00090001 Button 1 Primary/trigger (MULTI=Selector, On/Off, Momentary, or One Shot) 
29 0A          (LOCAL)  USAGE_MAXIMUM      0x0009000A Button 10 (MULTI=Selector, On/Off, Momentary, or One Shot) 
95 0A          (GLOBAL) REPORT_COUNT       0x0A (10) Number of fields  
81 02          (MAIN)   INPUT              0x00000002 (10 fields x 1 bit) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
19 0B          (LOCAL)  USAGE_MINIMUM      0x0009000B Button 11 (MULTI=Selector, On/Off, Momentary, or One Shot) 
29 0E          (LOCAL)  USAGE_MAXIMUM      0x0009000E Button 14 (MULTI=Selector, On/Off, Momentary, or One Shot) 
95 04          (GLOBAL) REPORT_COUNT       0x04 (4) Number of fields  
81 02          (MAIN)   INPUT              0x00000002 (4 fields x 1 bit) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
95 02          (GLOBAL) REPORT_COUNT       0x02 (2) Number of fields  
81 03          (MAIN)   INPUT              0x00000003 (2 fields x 1 bit) 1=Constant 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
05 01          (GLOBAL) USAGE_PAGE         0x0001 Generic Desktop Page 
09 01          (LOCAL)  USAGE              0x00010001 Pointer (CP=Physical Collection) 
A0             (MAIN)   COLLECTION         0x00000000 Physical (Usage=0x00010001: Page=Generic Desktop Page, Usage=Pointer, Type=CP)
09 30            (LOCAL)  USAGE              0x00010030 X (DV=Dynamic Value) 
09 31            (LOCAL)  USAGE              0x00010031 Y (DV=Dynamic Value) 
09 32            (LOCAL)  USAGE              0x00010032 Z (DV=Dynamic Value) 
09 35            (LOCAL)  USAGE              0x00010035 Rz (DV=Dynamic Value) 
27 FFFF0000      (GLOBAL) LOGICAL_MAXIMUM    0x0000FFFF (65535)  
75 10            (GLOBAL) REPORT_SIZE        0x10 (16) Number of bits per field  
95 04            (GLOBAL) REPORT_COUNT       0x04 (4) Number of fields  
81 02            (MAIN)   INPUT              0x00000002 (4 fields x 16 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
C0             (MAIN)   END_COLLECTION     Physical 
09 39          (LOCAL)  USAGE              0x00010039 Hat switch (DV=Dynamic Value) 
25 07          (GLOBAL) LOGICAL_MAXIMUM    0x07 (7)  
34             (GLOBAL) PHYSICAL_MINIMUM   (0) <-- Redundant: PHYSICAL_MINIMUM is already 0 
46 3B01        (GLOBAL) PHYSICAL_MAXIMUM   0x013B (315)  
65 14          (GLOBAL) UNIT               0x00000014 Rotation in degrees [1° units] (4=System=English Rotation, 1=Rotation=Degrees) 
75 04          (GLOBAL) REPORT_SIZE        0x04 (4) Number of bits per field  
95 01          (GLOBAL) REPORT_COUNT       0x01 (1) Number of fields  
81 02          (MAIN)   INPUT              0x00000002 (1 field x 4 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
B4             (GLOBAL) POP                USAGE_PAGE=0x0009 LOGICAL(MIN=0,MAX=1) PHYSICAL(MIN=0,MAX=0) UNIT(0x0,EXP=0) REPORT(ID=0x30,SIZE=1,COUNT=0)
19 0F          (LOCAL)  USAGE_MINIMUM      0x0009000F Button 15 (MULTI=Selector, On/Off, Momentary, or One Shot) 
29 12          (LOCAL)  USAGE_MAXIMUM      0x00090012 Button 18 (MULTI=Selector, On/Off, Momentary, or One Shot) 
95 04          (GLOBAL) REPORT_COUNT       0x04 (4) Number of fields  
81 02          (MAIN)   INPUT              0x00000002 (4 fields x 1 bit) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
26 FF00        (GLOBAL) LOGICAL_MAXIMUM    0x00FF (255)  
75 08          (GLOBAL) REPORT_SIZE        0x08 (8) Number of bits per field  
95 3F          (GLOBAL) REPORT_COUNT       0x3F (63) Number of fields  
06 00FF        (GLOBAL) USAGE_PAGE         0xFF00 Vendor-defined 
85 21          (GLOBAL) REPORT_ID          0x21 (33) 
09 01          (LOCAL)  USAGE              0xFF000001 <-- Warning: Undocumented usage
81 02          (MAIN)   INPUT              0x00000002 (63 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
85 81          (GLOBAL) REPORT_ID          0x81 (129) 
09 02          (LOCAL)  USAGE              0xFF000002 <-- Warning: Undocumented usage
81 02          (MAIN)   INPUT              0x00000002 (63 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
85 01          (GLOBAL) REPORT_ID          0x01 (1) 
09 03          (LOCAL)  USAGE              0xFF000003 <-- Warning: Undocumented usage
91 82          (MAIN)   OUTPUT             0x00000082 (63 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 1=Volatile 0=Bitmap 
85 10          (GLOBAL) REPORT_ID          0x10 (16) 
09 04          (LOCAL)  USAGE              0xFF000004 <-- Warning: Undocumented usage
91 82          (MAIN)   OUTPUT             0x00000082 (63 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 1=Volatile 0=Bitmap 
85 80          (GLOBAL) REPORT_ID          0x80 (128) 
09 05          (LOCAL)  USAGE              0xFF000005 <-- Warning: Undocumented usage
91 82          (MAIN)   OUTPUT             0x00000082 (63 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 1=Volatile 0=Bitmap 
85 82          (GLOBAL) REPORT_ID          0x82 (130) 
09 06          (LOCAL)  USAGE              0xFF000006 <-- Warning: Undocumented usage
91 82          (MAIN)   OUTPUT             0x00000082 (63 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 1=Volatile 0=Bitmap 
C0           (MAIN)   END_COLLECTION     Application 
*/

//--------------------------------------------------------------------------------
// Button Page inputReport 30 (Device --> Host)
//--------------------------------------------------------------------------------

typedef struct
{
  uint8_t  reportId;                                 // Report ID = 0x30 (48) '0'
                                                     // Collection: Joystick
  uint8_t  BTN_JoystickButton1 : 1;                  // Usage 0x00090001: Button 1 Primary/trigger, Value = 0 to 1
  uint8_t  BTN_JoystickButton2 : 1;                  // Usage 0x00090002: Button 2 Secondary, Value = 0 to 1
  uint8_t  BTN_JoystickButton3 : 1;                  // Usage 0x00090003: Button 3 Tertiary, Value = 0 to 1
  uint8_t  BTN_JoystickButton4 : 1;                  // Usage 0x00090004: Button 4, Value = 0 to 1
  uint8_t  BTN_JoystickButton5 : 1;                  // Usage 0x00090005: Button 5, Value = 0 to 1
  uint8_t  BTN_JoystickButton6 : 1;                  // Usage 0x00090006: Button 6, Value = 0 to 1
  uint8_t  BTN_JoystickButton7 : 1;                  // Usage 0x00090007: Button 7, Value = 0 to 1
  uint8_t  BTN_JoystickButton8 : 1;                  // Usage 0x00090008: Button 8, Value = 0 to 1
  uint8_t  BTN_JoystickButton9 : 1;                  // Usage 0x00090009: Button 9, Value = 0 to 1
  uint8_t  BTN_JoystickButton10 : 1;                 // Usage 0x0009000A: Button 10, Value = 0 to 1
  uint8_t  BTN_JoystickButton11 : 1;                 // Usage 0x0009000B: Button 11, Value = 0 to 1
  uint8_t  BTN_JoystickButton12 : 1;                 // Usage 0x0009000C: Button 12, Value = 0 to 1
  uint8_t  BTN_JoystickButton13 : 1;                 // Usage 0x0009000D: Button 13, Value = 0 to 1
  uint8_t  BTN_JoystickButton14 : 1;                 // Usage 0x0009000E: Button 14, Value = 0 to 1
  uint8_t  : 1;                                      // Pad
  uint8_t  : 1;                                      // Pad
                                                     // Collection: Joystick Pointer
  uint16_t GD_JoystickPointerX;                      // Usage 0x00010030: X, Value = 0 to 65535
  uint16_t GD_JoystickPointerY;                      // Usage 0x00010031: Y, Value = 0 to 65535
  uint16_t GD_JoystickPointerZ;                      // Usage 0x00010032: Z, Value = 0 to 65535
  uint16_t GD_JoystickPointerRz;                     // Usage 0x00010035: Rz, Value = 0 to 65535
                                                     // Collection: Joystick
  uint8_t  GD_JoystickHatSwitch : 4;                 // Usage 0x00010039: Hat switch, Value = 0 to 7, Physical = Value x 45 in degrees
  uint8_t  BTN_JoystickButton15 : 1;                 // Usage 0x0009000F: Button 15, Value = 0 to 1
  uint8_t  BTN_JoystickButton16 : 1;                 // Usage 0x00090010: Button 16, Value = 0 to 1
  uint8_t  BTN_JoystickButton17 : 1;                 // Usage 0x00090011: Button 17, Value = 0 to 1
  uint8_t  BTN_JoystickButton18 : 1;                 // Usage 0x00090012: Button 18, Value = 0 to 1
} inputReport30_t;


//--------------------------------------------------------------------------------
// Vendor-defined inputReport 21 (Device --> Host)
//--------------------------------------------------------------------------------

typedef struct
{
  uint8_t  reportId;                                 // Report ID = 0x21 (33)
  uint8_t  VEN_Joystick0001[63];                     // Usage 0xFF000001: , Value = 0 to 255
} inputReport21_t;


//--------------------------------------------------------------------------------
// Vendor-defined inputReport 81 (Device --> Host)
//--------------------------------------------------------------------------------

typedef struct
{
  uint8_t  reportId;                                 // Report ID = 0x81 (129)
  uint8_t  VEN_Joystick0002[63];                     // Usage 0xFF000002: , Value = 0 to 255
} inputReport81_t;


//--------------------------------------------------------------------------------
// Vendor-defined outputReport 01 (Device <-- Host)
//--------------------------------------------------------------------------------

typedef struct
{
  uint8_t  reportId;                                 // Report ID = 0x01 (1)
                                                     // Collection: Joystick
  uint8_t  VEN_Joystick0003[63];                     // Usage 0xFF000003: , Value = 0 to 255
} outputReport01_t;


//--------------------------------------------------------------------------------
// Vendor-defined outputReport 10 (Device <-- Host)
//--------------------------------------------------------------------------------

typedef struct
{
  uint8_t  reportId;                                 // Report ID = 0x10 (16)
  uint8_t  VEN_Joystick0004[63];                     // Usage 0xFF000004: , Value = 0 to 255
} outputReport10_t;


//--------------------------------------------------------------------------------
// Vendor-defined outputReport 80 (Device <-- Host)
//--------------------------------------------------------------------------------

typedef struct
{
  uint8_t  reportId;                                 // Report ID = 0x80 (128)
  uint8_t  VEN_Joystick0005[63];                     // Usage 0xFF000005: , Value = 0 to 255
} outputReport80_t;


//--------------------------------------------------------------------------------
// Vendor-defined outputReport 82 (Device <-- Host)
//--------------------------------------------------------------------------------

typedef struct
{
  uint8_t  reportId;                                 // Report ID = 0x82 (130)
  uint8_t  VEN_Joystick0006[63];                     // Usage 0xFF000006: , Value = 0 to 255
} outputReport82_t;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47902131

复制
相关文章

相似问题

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