与键盘通信的应用

本文关键字:应用 通信 键盘 | 更新日期: 2023-09-27 18:02:03

我创建了自己的可配置键盘设备(我可以更改任何键的代码)。现在我正在尝试编写c#应用程序,它将与此设备通信,但我对此有问题。

键盘设备报告描述符:

//Keyboard
0x05, 0x01,   // USAGE_PAGE (Generic Desktop)
    0x09, 0x06,   // USAGE (Keyboard)
    0xa1, 0x01,   // COLLECTION (Application)
    0x85, 0x01,   //   REPORT_ID (1)
    0x05, 0x07,   //   USAGE_PAGE (Keyboard)
    0x19, 0xe0,   //   USAGE_MINIMUM (Keyboard LeftControl)
    0x29, 0xe7,   //   USAGE_MAXIMUM (Keyboard Right GUI)
    0x15, 0x00,   //   LOGICAL_MINIMUM (0)
    0x25, 0x01,   //   LOGICAL_MAXIMUM (1)
    0x75, 0x01,   //   REPORT_SIZE (1)
    0x95, 0x08,   //   REPORT_COUNT (8)
    0x81, 0x02,   //   INPUT (Data,Var,Abs)
    0x95, 0x01,   //   REPORT_COUNT (1)
    0x75, 0x08,   //   REPORT_SIZE (8)
    0x81, 0x03,   //   INPUT (Cnst,Var,Abs)
    0x95, 0x05,   //   REPORT_COUNT (5)
    0x75, 0x01,   //   REPORT_SIZE (1)
    0x05, 0x08,   //   USAGE_PAGE (LEDs)
    0x19, 0x01,   //   USAGE_MINIMUM (Num Lock)
    0x29, 0x05,   //   USAGE_MAXIMUM (Kana)
    0x91, 0x02,   //   OUTPUT (Data,Var,Abs)
    0x95, 0x01,   //   REPORT_COUNT (1)
    0x75, 0x03,   //   REPORT_SIZE (3)
    0x91, 0x03,   //   OUTPUT (Cnst,Var,Abs)
    0x95, 0x06,   //   REPORT_COUNT (6)
    0x75, 0x08,   //   REPORT_SIZE (8)
    0x15, 0x00,   //   LOGICAL_MINIMUM (0)
    0x25, 0xFF,   //   LOGICAL_MAXIMUM (255) //0x25, 0x65,   //   LOGICAL_MAXIMUM (101)
    0x05, 0x07,   //   USAGE_PAGE (Keyboard)
    0x19, 0x00,   //   USAGE_MINIMUM (Reserved (no event indicated))
    0x29, 0x65,   //   USAGE_MAXIMUM (Keyboard Application)
    0x81, 0x00,   //   INPUT (Data,Ary,Abs)
0xc0,         // END_COLLECTION
/*65*/
//Device Configuration
0x06, 0xFF, 0xA0,  // USAGE_PAGE (Vendor-Defined)
    0x09, 0x01,    // USAGE (Vendor-Defined)
    0xA1, 0x01,    // COLLECTION (Application)
    0x85, 0x02,    // REPORT_ID (2)
    0x09, 0x03,    // USAGE (Vendor-Defined)
    0x15, 0x00,    // LOGICAL_MINIMUM (0)
    0x26, 0x00, 0xFF, // LOGICAL_MAXIMUM (255)
    0x95, 0x2D,    // REPORT_COUNT (45)
    0x75, 0x08,    // REPORT_SIZE (8)
    0x81, 0x02,    // Input (Data, Variable, Absolute)
    0x09, 0x04,    // USAGE (Vendor-Defined)
    0x15, 0x00,    // LOGICAL_MINIMUM (0)
    0x26, 0x00, 0xFF, // LOGICAL_MAXIMUM (255)
    0x95, 0x2D,    // REPORT_COUNT (45)
    0x75, 0x08,    // REPORT_SIZE (8)
    0x91, 0x02,    // Output (Data, Variable, Absolute)
    0x09, 0x05,    // USAGE (Vendor-Defined)
    0x15, 0x00,    // LOGICAL_MINIMUM (0)
    0x26, 0x00, 0xFF, // LOGICAL_MAXIMUM (255)
    0x95, 0x2D,    // REPORT_COUNT (45)
    0x75, 0x08,    // REPORT_SIZE (8)
    0xB1, 0x02,    // Feature (Data, Variable, Absolute)
0xc0,          //   END_COLLECTION

部分c#代码(我使用的是HIDLibrary):

    Device = HidDevices.Enumerate(VendorID, ProductID).FirstOrDefault();
    if (Device == null)
    {
        return;
    }
    //Open Device
    Device.OpenDevice();
    //if( Device.IsOpen == false )
    //  return;
    Device.Inserted += DeviceAttachedHandler;
    Device.Removed += DeviceRemovedHandler;
    Device.MonitorDeviceEvents = true;

    //Handle Reports
    KeyMapRequest(); //Fill Buffer with KeyMapRequest
    HidReport report = Device.CreateReport();
    report.ReportId = 2;
    report.Data = USBBuffer;
    succeed = Device.WriteReport(report, 10);
    Device.ReadReport(OnReport);
    LastDataEventDate = DateTime.Now;
    while ((DateTime.Now - LastDataEventDate).TotalMilliseconds < 100)
    {
    }

键盘工作正常,但应用程序无法与设备通信。"设备。IsOpen总是"false"。但是当我从报告描述符部分删除"Report_ID(1)"时(键盘部分),"设备。"IsOpen"是"真实的",通信工作正常。

Windows负责阻止通信吗?我该如何处理呢?或者我在描述符中有一些错误?

与键盘通信的应用

我认为这种行为可能是不正确的LOGICAL_MAXIMUM规范的副作用。你不小心把255编码成了-256。当我使用hidrdd解码你的声明时,它输出:

/*
06 FFA0      (GLOBAL) USAGE_PAGE         0xA0FF Reserved 
09 01        (LOCAL)  USAGE              0xA0FF0001  
A1 01        (MAIN)   COLLECTION         0x01 Application (Usage=0xA0FF0001: Page=Reserved, Usage=, Type=) <-- Warning: USAGE type should be CA (Application)
85 02          (GLOBAL) REPORT_ID          0x02 (2) 
09 03          (LOCAL)  USAGE              0xA0FF0003  
15 00          (GLOBAL) LOGICAL_MINIMUM    0x00 (0) <-- Redundant: LOGICAL_MINIMUM is already 0
26 00FF        (GLOBAL) LOGICAL_MAXIMUM    0xFF00 (-256) 
95 2D          (GLOBAL) REPORT_COUNT       0x2D (45) Number of fields 
75 08          (GLOBAL) REPORT_SIZE        0x08 (8) Number of bits per field <-- Redundant: REPORT_SIZE is already 8
81 02          (MAIN)   INPUT              0x00000002 (45 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap  <-- Error: REPORT_SIZE (8) is too small for LOGICAL_MAXIMUM (-256) which needs 9 bits. <-- Error: LOGICAL_MAXIMUM (-256) is less than LOGICAL_MINIMUM (0)
09 04          (LOCAL)  USAGE              0xA0FF0004  
15 00          (GLOBAL) LOGICAL_MINIMUM    0x00 (0) <-- Redundant: LOGICAL_MINIMUM is already 0
26 00FF        (GLOBAL) LOGICAL_MAXIMUM    0xFF00 (-256) <-- Redundant: LOGICAL_MAXIMUM is already -256
95 2D          (GLOBAL) REPORT_COUNT       0x2D (45) Number of fields <-- Redundant: REPORT_COUNT is already 45
75 08          (GLOBAL) REPORT_SIZE        0x08 (8) Number of bits per field <-- Redundant: REPORT_SIZE is already 8
91 02          (MAIN)   OUTPUT             0x00000002 (45 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap  <-- Error: REPORT_SIZE (8) is too small for LOGICAL_MAXIMUM (-256) which needs 9 bits. <-- Error: LOGICAL_MAXIMUM (-256) is less than LOGICAL_MINIMUM (0)
09 05          (LOCAL)  USAGE              0xA0FF0005  
15 00          (GLOBAL) LOGICAL_MINIMUM    0x00 (0) <-- Redundant: LOGICAL_MINIMUM is already 0
26 00FF        (GLOBAL) LOGICAL_MAXIMUM    0xFF00 (-256) <-- Redundant: LOGICAL_MAXIMUM is already -256
95 2D          (GLOBAL) REPORT_COUNT       0x2D (45) Number of fields <-- Redundant: REPORT_COUNT is already 45
75 08          (GLOBAL) REPORT_SIZE        0x08 (8) Number of bits per field <-- Redundant: REPORT_SIZE is already 8
B1 02          (MAIN)   FEATURE            0x00000002 (45 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap  <-- Error: REPORT_SIZE (8) is too small for LOGICAL_MAXIMUM (-256) which needs 9 bits. <-- Error: LOGICAL_MAXIMUM (-256) is less than LOGICAL_MINIMUM (0)
C0           (MAIN)   END_COLLECTION     Application
*/

在HID报告描述符中,您需要以Little-Endian顺序编码值。这也适用于USAGE_PAGE(我已经更正了下面的示例)。

顺便说一句,您不需要重复LOGICAL_MINIMUM, LOGICAL_MAXIMUM, REPORT_COUNT或REPORT_SIZE值,因为它们都是GLOBAL项-所以它们只需要在它们的值改变时指定(当解析器扫描它们时)。试说明:

/*
06 A0FF      (GLOBAL) USAGE_PAGE         0xFFA0 Vendor-defined 
09 01        (LOCAL)  USAGE              0xFFA00001  
A1 01        (MAIN)   COLLECTION         0x01 Application (Usage=0xFFA00001: Page=Vendor-defined, Usage=, Type=)
85 02          (GLOBAL) REPORT_ID          0x02 (2) 
09 03          (LOCAL)  USAGE              0xFFA00003  
15 00          (GLOBAL) LOGICAL_MINIMUM    0x00 (0) <-- Redundant: LOGICAL_MINIMUM is already 0
26 FF00        (GLOBAL) LOGICAL_MAXIMUM    0x00FF (255) 
95 2D          (GLOBAL) REPORT_COUNT       0x2D (45) Number of fields 
75 08          (GLOBAL) REPORT_SIZE        0x08 (8) Number of bits per field <-- Redundant: REPORT_SIZE is already 8
81 02          (MAIN)   INPUT              0x00000002 (45 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
09 04          (LOCAL)  USAGE              0xFFA00004  
91 02          (MAIN)   OUTPUT             0x00000002 (45 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
09 05          (LOCAL)  USAGE              0xFFA00005  
B1 02          (MAIN)   FEATURE            0x00000002 (45 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
C0           (MAIN)   END_COLLECTION     Application
*/