Недавно я купил модуль сканера штрих-кода 2D из Китая. В соответствии с их спецификацией, он работал с точными штрих-кодами сканирования, когда я открывал блокнот. Все, что мне нужно сделать, это попробовать использовать libusb и прочитать штрих-код на моем c-коде. Я использую Intel edison с платой Adrunio, которая настроена как хост usb.Устройство HID не может получить фактическое значение
У меня установлен 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
И мой с код:
#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 bytes
и bLength 18
, он дал мне ошибку, когда я пробовал с длиной как 8,16,18. Таким образом, я изменился на 24. Мой фактический размер штрих-кода (1D) составляет 12 байт.
Это что-то не так в коде, или мне нужно добавить больше ядра для чтения реального барда.
Действительно ли все байты равны нулю? Обычно 1 или 2 из 8 байтов должны иметь значение! = 0, где все остальные должны быть равны 0, потому что именно так работает HID. – dryman
не все первые и 3-й байты имеют некоторые значения в нем – kar
Да, как вы уже писали в своем ответе, вы получили только данные HID. Это должно быть так. – dryman