LibUSB通过SetReport()请求与USBHID设备通信

自从基于libUSB的USB设备固件更新程序(下载数据)之后,好久没时间继续我的USB折腾了。今天继续。
本文开发环境:Win7
上位机编译环境:VC++ Express 2010
libusb-win32-devel-filter-1.2.6
首先,安装所需要控制的设备的LibUSB-Win32 Filter,注意:不是LibUSB-Win32本身啊,否则LibUSB驱动程序或替代M$的默认USBHID类设备驱动程序,结果是USBHID设备没有反应。
然后,开始编写上位机程序:
按照LibUSB文档说明的操作顺序,先打开设备:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//此处VID、PID为测试用,工业生产请勿使用,如有冒犯贵公司,请及时指出以便我们修改
#define MY_VID 0x0666
#define MY_PID 0x0001
#define MY_CONFIG 0x01
usb_init ( ) ;  /* initialize the library */
usb_find_busses ( ) ;  /* find all busses */
usb_find_devices ( ) ;  /* find all connected devices */
if ( ! (dev  = open_dev ( ) ) )  {
printf ( "error opening device: \n%s\n", usb_strerror ( ) ) ;
printf ( "Is your USB-Device successfully pluged in?\n\n" ) ;
}
else  {
printf ( "success: device %04X:%04X opened\n", MY_VID, MY_PID ) ;
}
if (usb_set_configuration (dev, MY_CONFIG )  &lt ;  0 )  {
printf ( "error setting config #%d: %s\n", MY_CONFIG, usb_strerror ( ) ) ;
printf ( "Is your USB-Device running?\n\n" ) ;
usb_close (dev ) ;
}
else
{
printf ( "success: set configuration #%d\n", MY_CONFIG ) ;
}

if (usb_claim_interface (dev,  0 )  &lt ;  0 )  {
printf ( "error claiming interface #%d:\n%s\n", MY_INTF, usb_strerror ( ) ) ;
printf ( "Please check your USB-Device's firmware!\n\n" ) ;
usb_close (dev ) ;
}
else  {
printf ( "success: claim interface #%d\n", MY_INTF ) ;
}

此时已经成功打开设备的接口1。接下来,可以发送SetReport()请求。
根据USB HID协议规范,Set Report()请求总长8个字节,分为bmRequestType、bRequest、wValue(2 bytes)、wIndex(2 bytes)、wLength(2 bytes)。需要注意的是,USB请求都是低位在前,也就是说,一个WORD的低8位先传输,高8位后传输。这8个字节的请求之后,通过Control transfer 的 Output端点下发数据。

  • bmRequestType=0×21;表示USBHID类请求;
  • bRequest=0×09;表示SetReport()请求;
  • wValue=0×0003;Report ID = 0,Report Type = 0×03(01:Input,02:Output,03:Feature,04-ff:Reserved)表示通过Feature Report发送数据(USB键盘的LED是通过Output Report发送的数据)。
  • wIndex=0×0000;表示选择端点0。
  • wLength=0×0300;表示数据长度是3 bytes

接下来通过控制传输的输出端点发送3 bytes的数据:char ShiftMouseScrollDown1[] = {0x02,0xf3,0xff};

具体在LibUSB中,是使用usb_control_msg()函数实现的,该函数的原型为:

1
2
3
4
int usb_control_msg (usb_dev_handle  *dev, 
         int requesttype,  int request, 
         int value,  int index,  char  *bytes,  int size, 
         int timeout ) ;

usb_control_msg 函数在默认控制管道发送控制请求,该函数的参数符合标准USB的数据规范。
对照上方的数解释,构建出这些函数参数

1
2
3
4
5
6
7
8
9
10
    ret  = usb_control_msg (dev,  0x210x09,
                 0x03000x0000, ShiftMouseScrollDown1,  3,
                 1000 ) ; //1000 ms timeout
     if (ret  <  0 )  {
         printf ( "error writing:\n%s\n", usb_strerror ( ) ) ;
     }
     else
     {
         printf ( "success! COMMAND sent in %d bytes\n", ret ) ;
     }

至此,数据发送完成。通过Bus Hound软件应该可以捕捉到传输的数据。
需要多次发送的话,多次调用usb_control_msg()即可。
发送完成之后的关闭USB接口操作,

1
2
    usb_release_interface (dev, MY_INTF ) ;
    usb_close (dev ) ;

一些基础细节,请参考我之前的博文
基于libUSB的USB设备固件更新程序

可能出现的问题:

  1. 不小心安装了LibUSB-Win32驱动程序,此时不要惊慌,直接使用USBDeview这个小软件,找到对应的设备,卸载(其驱动程序),重新拔插一次设备即可恢复系统驱动。
0
本文链接: http://gcdn.gamepader.com/archives/2012/12/the-libusb-through-setreport-request-with-usbhid-device-communication.html

你可能感兴趣的:(LibUSB通过SetReport()请求与USBHID设备通信)