如何解决将 Windows API 移植到 linux,USB HID 设备读取
我使用 USB HID 设备,一个带 LED 的按钮。现有两个 API 用于访问设备。一种用于 Windows,一种用于 linux。不幸的是,linux API 没有读取按钮状态(按下/释放)的功能,但 windows API 确实有这个功能。我想将现有功能移植到 linux API。我已经尝试了几次,但仍然无法从 USB 设备获取数据。
现有和功能窗口实现从设备读取的步骤:
-
然后对与之前写入相同的结构进行读取操作。读取状态的位置与之前写入时放置 0x02 的位置相同。
PACDRIVE_API BOOL __stdcall USBButtonGetState(INT id,PBOOL state) { if(m_hidDeviceData[id].Type != DEVICETYPE_USBBUTTON) 错误;
REPORT_BUF reportBuffer; BOOL retVal = FALSE; reportBuffer.ReportID = 0; reportBuffer.ReportBuffer[0] = 0x02; reportBuffer.ReportBuffer[1] = 0x00; reportBuffer.ReportBuffer[2] = 0x00; reportBuffer.ReportBuffer[3] = 0x00; retVal = UsbWrite(&m_hidDeviceData[id],&reportBuffer); if(!retVal) return retVal; memset(&reportBuffer,sizeof(REPORT_BUF)); retVal = UsbRead(&m_hidDeviceData[id],&reportBuffer); if(!retVal) return retVal; *state = reportBuffer.ReportBuffer[0]; return retVal;
}
在 linux API 中,他们使用 libusb-1.0/libusb.h 库, 现有的用于设置按钮颜色的写入函数正在使用 libusb_control_transfer 函数:
bool writeUSBButton(unsigned char* barray,int autoconnect,bool transfer,unsigned int size)
{
libusb_context *ctx = NULL;
struct libusb_device_handle *handle = NULL;
unsigned char mesg[USBBTN_MESG_LENGTH] = {0,0};
bool result = true;
int pos = 0;
int ret = 0;
if (transfer)
{
handle = openUSB(ctx,USBBTN_vendOR,USBBTN_PRODUCT,USBBTN_INTERFACE,autoconnect);
if (!handle)
{
result = false;
goto error;
}
}
while (pos < size)
{
memcpy(&mesg[0],&barray[pos],4);
debug ("Writing (%i): %x,%x,%x",pos,mesg[0],mesg[1],mesg[2],mesg[3]);
if (transfer)
{
ret = libusb_control_transfer(handle,UM_REQUEST_TYPE,UM_REQUEST,USBBTN_VALUE,mesg,USBBTN_MESG_LENGTH,UM_TIMEOUT);
debug ("Write result: %i",ret);
}
pos+=USBBTN_MESG_LENGTH;
}
exit:
if (transfer)
{
closeUSB(ctx,handle,USBBTN_INTERFACE);
}
else
{
log_info ("board array was not written out!!!");
}
return result;
error:
return result;
}
我现在尝试以与写入功能相同的方式读取 USB 设备,但使用不同的 libusb_control_transfer 的参数,
> Setup Data (write)
> bmRequestType: 0x21
> 0... .... = Direction: Host-to-device
> .01. .... = Type: Class (0x1)
> ...0 0001 = Recipient: Interface (0x01)
> 0010 0001 -> 0x21(hex)
我用这个参数来读取:
> Setup Data (read)
> bmRequestType:
> 1... .... = Direction: Device to Host
> .01. .... = Type: Class (0x1)
> ...0 0000 = Recipient: Device (0x00)
> 1010 0000 -> 0xa0(hex)
不工作的代码:
bool readUSBButton(unsigned char* barray,unsigned int size)
{
// barray[0] = 0x02;
// barray[1] = 0x00;
// barray[2] = 0x00;
// barray[3] = 0x00;
// result = writeUSBButton(barray,1,true,USBBTN_MESG_LENGTH);
libusb_context *ctx = NULL;
struct libusb_device_handle *handle = NULL;
// USBBTN_MESG_LENGTH = 4
unsigned char mesg[USBBTN_MESG_LENGTH] = {0,autoconnect);
if (!handle)
{
result = false;
goto error;
}
}
while (pos < size)
{
debug ("reading (%i): %x,mesg[3]);
if (transfer)
{
uint8_t buttonData;
ret = libusb_control_transfer (handle,0xA0,2,&buttonData,0);
printf(" #### Read: %x ###### ret= %i",buttonData,ret);
debug ("read result: %i",USBBTN_INTERFACE);
}
else
{
log_info ("board array was not read !!!");
}
return result;
error:
return result;
}
lsusb -v 为我的设备输出:
Bus 001 Device 006: ID d209:1200 Ultimarc
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idvendor 0xd209 Ultimarc
idProduct 0x1200
bcdDevice 0.01
iManufacturer 2 USBButton
iProduct 2 USBButton
iSerial 1 1
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x003b
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 2 USBButton
bmAttributes 0xa0
(Bus Powered)
Remote Wakeup
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 2 USBButton
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.11
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 33
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 10
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 1 Boot Interface Subclass
bInterfaceProtocol 1 Keyboard
iInterface 2 USBButton
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.11
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 168
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 10
can't get device qualifier: Resource temporarily unavailable
can't get debug descriptor: Resource temporarily unavailable
Device Status: 0x0000
(Bus Powered)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。