【问题标题】:HID device cannot able to get actual valueHID 设备无法获取实际值
【发布时间】:2016-05-18 14:45:13
【问题描述】:

我最近从中国购买了一个二维条码扫描器模块。根据他们的数据表,当我打开记事本时,它可以很好地扫描条形码。我需要做的就是尝试使用 libusb 并读取我的 c 代码上的条形码。我使用英特尔爱迪生和配置为 USB 主机的 Adrunio 分线板。

我已经安装了 libusb-1.0.20,不幸的是我无法安装 libusb-1.0.20-devel。请注意,我在这里没有使用 libusbx 和 libusbx-devel。

由于它是条码扫描设备,它应该被检测为 HID 键盘。是的。

Bus 001 Device 003: ID 1eab:8203
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  idVendor           0x1eab
  idProduct          0x8203
  bcdDevice            1.00
  iManufacturer           1 NewLand
  iProduct                2 HidKeyBoard
  iSerial                 0
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           34
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              200mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      1 Boot Interface Subclass
      bInterfaceProtocol      1 Keyboard
      iInterface              0
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.10
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      63
         Report Descriptors:
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x84  EP 4 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval               1
Device Status:     0x0001
  Self Powered

而我的 c 代码是:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
//gcc -o usbtest usbtest.c -lusb-1.0
//libusbx-devel, libusbx
#include <libusb-1.0/libusb.h>
void print_devices(libusb_device *dev)
{
    struct libusb_device_descriptor desc;
    struct libusb_config_descriptor *config;
    const struct libusb_interface *inter;
    const struct libusb_interface_descriptor *interdesc;
    const struct libusb_endpoint_descriptor *endpointdesc;

int ret;
int i,j,k;

ret = libusb_get_device_descriptor(dev, & desc);
if(ret < 0)
{
    fprintf(stderr, "error in getting device descriptor\n");
    return;
}

printf("Number of possible configs is %d\n",desc.bNumConfigurations);
printf("Vendor ID  : 0x%x\n", desc.idVendor);
printf("Product ID : 0x%x\n", desc.idProduct);

libusb_get_config_descriptor(dev, 0, &config);

printf("Interface %d\n", config->bNumInterfaces);

for(i=0; i < config->bNumInterfaces; i++)
{
    inter = &config->interface[i];
    printf("Number of alternate settings : %d\n", inter->num_altsetting);
    for(j=0; j < inter->num_altsetting; j++)
    {
        interdesc = &inter->altsetting[j];
        printf("   Interface number : %d, ", interdesc->bInterfaceNumber);
        printf("   Num of endpoints : %d\n", interdesc->bNumEndpoints);
        for(k=0; k < interdesc->bNumEndpoints; k++)
        {
            endpointdesc = &interdesc->endpoint[k];
            printf("     Desc type : %d ",endpointdesc->bDescriptorType);
            printf("      EP Addr: %d\n", endpointdesc->bEndpointAddress);
        }
    }
}
printf("\n\n");
libusb_free_config_descriptor(config);
}


int main(int argc, char *argv[])
{
    libusb_device **devs; //pointer to pointer of device, used to retrieve a list of devices
    libusb_context *context = NULL; //a libusb session
    libusb_device_handle *dev_handle; //a device handle

size_t list;
size_t iter;
int retVal;
int kernelDriverDetached     = 0;  /* Set to 1 if kernel driver detached */

retVal = libusb_init(&context);
if(retVal < 0)
{
    perror("libusb_init");
    exit(1);
}

libusb_set_debug(context, 3); //set verbosity level to 3, as suggested in the documentation

list = libusb_get_device_list(context, &devs);
if(list < 0){
    fprintf(stderr, "Error in getting device list\n");
    libusb_free_device_list(devs, 1);
    libusb_exit(context);
    exit(1);
}

printf("There are %d devices found\n",list);

for(iter = 0; iter < list; iter++)
{
    /* print devices specs */
    print_devices(devs[iter]);
}

dev_handle = libusb_open_device_with_vid_pid(context, 0x1eab, 0x8203/*0x1d6b,0x0002*/); //these are vendorID and productID I found for my usb device
    if(dev_handle == NULL) {
    fprintf(stderr, "Unable to open device.\n");
        return 1;

}

/* Check whether a kernel driver is attached to interface #0. If so, we'll 
 * need to detach it.
 */
if (libusb_kernel_driver_active(dev_handle, 0))
{
        retVal = libusb_detach_kernel_driver(dev_handle, 0);
        if (retVal == 0)
        {
            kernelDriverDetached = 1;
        }
        else
        {
            fprintf(stderr, "Error detaching kernel driver.\n");
            return 1;
        }
}

/* Claim interface #0. */
retVal = libusb_claim_interface(dev_handle, 0);
if (retVal != 0)
{
        fprintf(stderr, "Error claiming interface.\n");
        return 1;
}

printf("Scanner Device Opened\n");

    struct libusb_transfer *transfer = libusb_alloc_transfer(0);
char buf[24];
int actualbytes;    
retVal = libusb_interrupt_transfer(dev_handle, /*0x84*/(4 | LIBUSB_ENDPOINT_IN), buf, 24, &actualbytes, 0);
if(retVal == 0) {
    printf("Received %d bytes\n",actualbytes);
}
else
{
    fprintf(stderr, "Error Receiving message. retVal : %d, Actual : %d\n",retVal,actualbytes);
}

for(iter = 0; iter < actualbytes; iter++){
    printf("Data[%d] = %d\n",iter,buf[iter]);
}

/* Release interface #0. */
retVal = libusb_release_interface(dev_handle, 0);
if (0 != retVal)
{
        fprintf(stderr, "Error releasing interface.\n");
}

/* If we detached a kernel driver from interface #0 earlier, we'll now 
 * need to attach it again.  */
if (kernelDriverDetached)
{
        libusb_attach_kernel_driver(dev_handle, 0);
}

/* Shutdown libusb. */
libusb_free_device_list(devs, 1); //free the list, unref the devices in it
libusb_exit(context);


return 0;
}

我可以编译和运行代码、扫描、打开、读取设备。但是我能读到的数据都是零。即使它说wMaxPacketSize 0x0008 1x 8 bytesbLength 18,当我尝试将长度设置为 8、16、18 时,它还是给了我错误。所以我改为 24。我的实际条码 (1D) 数据大小为 12 字节。

是代码有问题还是我需要添加更多核心来读取实际的条码。

【问题讨论】:

  • 真的所有字节都为零吗?通常 8 个字节中的 1 或 2 个应该有一个值 != 0 ,其中所有剩余的应该是 0,因为这就是 HID 的工作原理。
  • 并非所有第一个和第三个字节都有一些值
  • 是的,就像您已经在答案中写的那样,您只获得了 HID 数据。应该是这样的。

标签: barcode-scanner hid libusb-1.0 intel-edison


【解决方案1】:

我了解到,由于它检测为 HID 键盘设备,因此我收到的数据不会是 ASCII 格式(这是我所期望的)。我已经按照https://www.win.tue.nl/~aeb/linux/kbd/scancodes-14.html修改了代码

即使文档说的是 16 位键码,我也只有在读取 16 个字节时才能获得正确的数据。基于键码,我创建了一个将 HID 键码转换为 ASCII 的表。

但这仍然无法在我的 Windows 机器上运行,因为它说它无法打开设备。

【讨论】:

  • 关于无法在 Windows 上运行的问题:您是否安装了后端驱动器? Windows 不会在不更改驱动程序的情况下放弃 HID 键盘和鼠标。
  • 我正在努力。它是 libusb-win32 还是 WinUSB?有什么具体的链接可以帮助我
  • 由于您使用 libusb 1,您可以选择自己喜欢的。 libusb-win32 是 afaik 开源但不再维护,WinUSB 是专有的但由 Microsoft 维护。为 libusb 创建和/或安装驱动程序的一种简单方法是 Zadig。 Zadig 或多或少自动化了整个过程。
  • @dryman: yeah.. i am trying with Zadig but when choose my device it say it has HidUsb (v10.0.10586.306).我是否需要更换驱动程序。当我尝试同时使用 libusb-win32 (v1.2.6.0) 和/或 WinUSB (v6.1.7600.16385) 时,它给了我一条错误消息,提示安装失败。
  • 当我尝试执行使用 libusb 的代码时,我收到了类似libusb: warning [windows_get_device_list] could not retrieve port number for device '\\.\ROOT#INTEL_UOIP_BUS_DRIVER#0000', skipping: [13] The data is invalid. libusb: warning [hid_open] could not open HID device in R/W mode (keyboard or mouse?) - trying without libusb: error [hid_submit_bulk_transfer] unable to match endpoint to an open interface - cancelling transfer的消息
猜你喜欢
  • 1970-01-01
  • 2012-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-20
  • 2013-01-23
  • 1970-01-01
  • 2016-10-28
相关资源
最近更新 更多