libusb1.0学习

来源:互联网 发布:syslog端口 编辑:程序博客网 时间:2024/05/15 00:03

作者:AAA20090987

转自:http://blog.csdn.net/small_qch/article/details/6625111


接学习一,学习二主要是看例程

ok,现在最简单的想法看看有多少信息包含在你的设备里,程序代码如下


[cpp] view plaincopyprint?
  1. #include <iostream>  
  2. #include <libusb.h>  
  3. using namespace std;  
  4.    
  5. void printdev(libusb_device *dev); //prototype of the function  
  6.    
  7. int main() {  
  8.     libusb_device **devs; //pointer to pointer of device, used to retrieve a list of devices  
  9.     libusb_context *ctx = NULL; //a libusb session  
  10.     int r; //for return values  
  11.     ssize_t cnt; //holding number of devices in list  
  12.     r = libusb_init(&ctx); //initialize a library session  
  13.     if(r < 0) {  
  14.         cout<<"Init Error "<<r<<endl; //there was an error  
  15.         return 1;  
  16.     }  
  17.     libusb_set_debug(ctx, 3); //set verbosity level to 3, as suggested in the documentation  
  18.     cnt = libusb_get_device_list(ctx, &devs); //get the list of devices  
  19.    
  20.     if(cnt < 0) {  
  21.         cout<<"Get Device Error"<<endl; //there was an error  
  22.     }  
  23.     cout<<cnt<<" Devices in list."<<endl; //print total number of usb device  
  24.     ssize_t i; //for iterating through the list  
  25.    
  26.     for(i = 0; i < cnt; i++) {  
  27.         printdev(devs[i]); //print specs of this device  
  28.     }  
  29.     libusb_free_device_list(devs, 1); //free the list, unref the devices in it  
  30.     libusb_exit(ctx); //close the session  
  31.     return 0;  
  32. }  
  33.    
  34. void printdev(libusb_device *dev) {  
  35.     libusb_device_descriptor desc;  
  36.     int r = libusb_get_device_descriptor(dev, &desc);  
  37.     if (r < 0) {  
  38.         cout<<"failed to get device descriptor"<<endl;  
  39.         return;  
  40.     }  
  41.    
  42.     cout<<"Number of possible configurations: "<<(int)desc.bNumConfigurations<<"  ";  
  43.     cout<<"Device Class: "<<(int)desc.bDeviceClass<<"  ";  
  44.     cout<<"VendorID: "<<desc.idVendor<<"  ";  
  45.     cout<<"ProductID: "<<desc.idProduct<<endl;  
  46.     libusb_config_descriptor *config;  
  47.     libusb_get_config_descriptor(dev, 0, &config);  
  48.     cout<<"Interfaces: "<<(int)config->bNumInterfaces<<" ||| ";  
  49.     const libusb_interface *inter;  
  50.     const libusb_interface_descriptor *interdesc;  
  51.     const libusb_endpoint_descriptor *epdesc;  
  52.    
  53.     for(int i=0; i<(int)config->bNumInterfaces; i++) {  
  54.         inter = &config->interface[i];  
  55.         cout<<"Number of alternate settings: "<<inter->num_altsetting<<" | ";  
  56.         for(int j=0; j<inter->num_altsetting; j++) {  
  57.             interdesc = &inter->altsetting[j];  
  58.             cout<<"Interface Number: "<<(int)interdesc->bInterfaceNumber<<" | ";  
  59.             cout<<"Number of endpoints: "<<(int)interdesc->bNumEndpoints<<" | ";  
  60.    
  61.             for(int k=0; k<(int)interdesc->bNumEndpoints; k++) {  
  62.                 epdesc = &interdesc->endpoint[k];  
  63.                 cout<<"Descriptor Type: "<<(int)epdesc->bDescriptorType<<" | ";  
  64.                 cout<<"EP Address: "<<(int)epdesc->bEndpointAddress<<" | ";  
  65.             }  
  66.         }  
  67.     }  
  68.     cout<<endl<<endl<<endl;  
  69.     libusb_free_config_descriptor(config);  
  70. }  


写完之后,编译看看会出现什么。首先运行程序并检查设备,然后连上我自己的设备在执行程序。会发现有新的内容出现,可以根据vendor id和product id发现这正是我自己连上打开的设备。
注意:发现设备(调用libusb_get_device_list())会返回新的内存分配的设备队列。当你完成这个队列的使用后必须释放他。
Libusb同样需要知道当一切完成时清除队列的内容;设备的本身。
为处理这些问题,libusb提供了两个单独的条目:
一个释放队列本身的函数
一个针对设备内部的参考计数系统
新的设备由libusb_get_device_list()函数展示,都拥有一个参考计数1。你可以使用libubs_ref_device()和libusb_unref_device()增加或减少参考计数。当一个设备的参考计数为0时,该设备就被销毁
通过以上的信息,打开设备的基本流程可以视为如下步骤:
1. 使用libusb_get_device_list()发现设备;
2. 选择你想操作的设备,调用libusb_open();
3. 在设备队列中unref所有的设备;
4. 释放已经发现的设备队列;
这个次序是十分重要的,在尝试打开设备之前,你不能够unreference设备,因此unreference操作有可能导致设备的销毁。
为了方便起见,libusb_free_device_list()函数包含一个参数,在释放队列本身前,该参数能够选择性地在队列中unreference所有设备。这包含了以上的步骤3和步骤4。
如果还有需要,可以去libusb1’s API(http://libusb.sourceforge.net/api-1.0/index.html)文档参考你需要的函数。
好了,现在你可以找到你需要的设备了。现在是打开设备,请求并且执行一个简单的I/O。如果你知道vendor ID和prouct ID,使用libusb_open_device_with_vid_pid。
另外需要注意的,如果内核(你的OS)已经连接到这个设备,你将无法请求到它。在这种情况下,你需要调用libusb_detach_kernel_drive来从内核中检测设备。如果你想知道内核是否可用的,使用libusb_kernel_drive_active,如果返回值为1,对于你的设备内核可以加载驱动。
批量传输
为了在你的设备上使用批量传输,你应该获得为你的USB设备获得一个设备句柄,并且你应该知道使用哪个端点(从之前设备说明获得)。
关于语法上的信息参考这里(http://libusb.sourceforge.net/api-1.0/group__syncio.html#gab8ae853ab492c22d707241dc26c8a805)
这里有个简单的例子包含所有我提到的相关部分:

[cpp] view plaincopyprint?
  1. #include <iostream>  
  2. #include <libusb.h>  
  3.    
  4. using namespace std;  
  5.    
  6. int main() {  
  7.     libusb_device **devs; //pointer to pointer of device, used to retrieve a list of devices  
  8.     libusb_device_handle *dev_handle; //a device handle  
  9.     libusb_context *ctx = NULL; //a libusb session  
  10.     int r; //for return values  
  11.     ssize_t cnt; //holding number of devices in list  
  12.     r = libusb_init(&ctx); //initialize the library for the session we just declared  
  13.    
  14.     if(r < 0) {  
  15.         cout<<"Init Error "<<r<<endl; //there was an error  
  16.         return 1;  
  17.     }  
  18.     libusb_set_debug(ctx, 3); //set verbosity level to 3, as suggested in the documentation  
  19.    
  20.     cnt = libusb_get_device_list(ctx, &devs); //get the list of devices  
  21.     if(cnt < 0) {  
  22.         cout<<"Get Device Error"<<endl; //there was an error  
  23.         return 1;  
  24.     }  
  25.     cout<<cnt<<" Devices in list."<<endl;  
  26.    
  27.     dev_handle = libusb_open_device_with_vid_pid(ctx, 5118, 7424); //these are vendorID and productID I found for my usb device  
  28.     if(dev_handle == NULL)  
  29.         cout<<"Cannot open device"<<endl;  
  30.     else  
  31.         cout<<"Device Opened"<<endl;  
  32.     libusb_free_device_list(devs, 1); //free the list, unref the devices in it  
  33.    
  34.     unsigned char *data = new unsigned char[4]; //data to write  
  35.     data[0]='a';data[1]='b';data[2]='c';data[3]='d'//some dummy values  
  36.    
  37.     int actual; //used to find out how many bytes were written  
  38.     if(libusb_kernel_driver_active(dev_handle, 0) == 1) { //find out if kernel driver is attached  
  39.         cout<<"Kernel Driver Active"<<endl;  
  40.         if(libusb_detach_kernel_driver(dev_handle, 0) == 0) //detach it  
  41.             cout<<"Kernel Driver Detached!"<<endl;  
  42.     }  
  43.     r = libusb_claim_interface(dev_handle, 0); //claim interface 0 (the first) of device (mine had jsut 1)  
  44.     if(r < 0) {  
  45.         cout<<"Cannot Claim Interface"<<endl;  
  46.         return 1;  
  47.     }  
  48.     cout<<"Claimed Interface"<<endl;  
  49.    
  50.     cout<<"Data->"<<data<<"<-"<<endl; //just to see the data we want to write : abcd  
  51.     cout<<"Writing Data..."<<endl;  
  52.     r = libusb_bulk_transfer(dev_handle, (2 | LIBUSB_ENDPOINT_OUT), data, 4, &actual, 0); //my device's out endpoint was 2, found with trial- the device had 2 endpoints: 2 and 129  
  53.     if(r == 0 && actual == 4) //we wrote the 4 bytes successfully  
  54.         cout<<"Writing Successful!"<<endl;  
  55.     else  
  56.         cout<<"Write Error"<<endl;  
  57.    
  58.     r = libusb_release_interface(dev_handle, 0); //release the claimed interface  
  59.     if(r!=0) {  
  60.         cout<<"Cannot Release Interface"<<endl;  
  61.         return 1;  
  62.     }  
  63.     cout<<"Released Interface"<<endl;  
  64.    
  65.     libusb_close(dev_handle); //close the device we opened  
  66.     libusb_exit(ctx); //needs to be called to end the  
  67.    
  68.     delete[] data; //delete the allocated memory for data  
  69.     return 0;  
  70. }  

结尾:这个教程对于这个话题来说是十分简单的介绍,需要时间需联系同步传输,然后移动是异步的,这还有很多需要学习。
希望这些对你的初学有帮助。


原文连接:http://blog.cnnbboy.com/?p=313


0 0
原创粉丝点击