libusb1.0學習

來源:互聯網
上載者:User
接學習一,學習二主要是看常式

ok,現在最簡單的想法看看有多少資訊包含在你的裝置裡,程式碼如下


#include <iostream>#include <libusb.h>using namespace std; void printdev(libusb_device *dev); //prototype of the function int main() {    libusb_device **devs; //pointer to pointer of device, used to retrieve a list of devices    libusb_context *ctx = NULL; //a libusb session    int r; //for return values    ssize_t cnt; //holding number of devices in list    r = libusb_init(&ctx); //initialize a library session    if(r < 0) {        cout<<"Init Error "<<r<<endl; //there was an error        return 1;    }    libusb_set_debug(ctx, 3); //set verbosity level to 3, as suggested in the documentation    cnt = libusb_get_device_list(ctx, &devs); //get the list of devices     if(cnt < 0) {        cout<<"Get Device Error"<<endl; //there was an error    }    cout<<cnt<<" Devices in list."<<endl; //print total number of usb device    ssize_t i; //for iterating through the list     for(i = 0; i < cnt; i++) {        printdev(devs[i]); //print specs of this device    }    libusb_free_device_list(devs, 1); //free the list, unref the devices in it    libusb_exit(ctx); //close the session    return 0;} void printdev(libusb_device *dev) {    libusb_device_descriptor desc;    int r = libusb_get_device_descriptor(dev, &desc);    if (r < 0) {        cout<<"failed to get device descriptor"<<endl;        return;    }     cout<<"Number of possible configurations: "<<(int)desc.bNumConfigurations<<"  ";    cout<<"Device Class: "<<(int)desc.bDeviceClass<<"  ";cout<<"VendorID: "<<desc.idVendor<<"  ";    cout<<"ProductID: "<<desc.idProduct<<endl;    libusb_config_descriptor *config;    libusb_get_config_descriptor(dev, 0, &config);    cout<<"Interfaces: "<<(int)config->bNumInterfaces<<" ||| ";    const libusb_interface *inter;    const libusb_interface_descriptor *interdesc;    const libusb_endpoint_descriptor *epdesc;     for(int i=0; i<(int)config->bNumInterfaces; i++) {        inter = &config->interface[i];        cout<<"Number of alternate settings: "<<inter->num_altsetting<<" | ";        for(int j=0; j<inter->num_altsetting; j++) {            interdesc = &inter->altsetting[j];            cout<<"Interface Number: "<<(int)interdesc->bInterfaceNumber<<" | ";            cout<<"Number of endpoints: "<<(int)interdesc->bNumEndpoints<<" | ";             for(int k=0; k<(int)interdesc->bNumEndpoints; k++) {                epdesc = &interdesc->endpoint[k];                cout<<"Descriptor Type: "<<(int)epdesc->bDescriptorType<<" | ";                cout<<"EP Address: "<<(int)epdesc->bEndpointAddress<<" | ";            }        }    }    cout<<endl<<endl<<endl;    libusb_free_config_descriptor(config);}

寫完之後,編譯看看會出現什麼。首先運行程式並檢查裝置,然後連上我自己的裝置在執行程式。會發現有新的內容出現,可以根據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)
這裡有個簡單的例子包含所有我提到的相關部分:

#include <iostream>#include <libusb.h> using namespace std; int main() {    libusb_device **devs; //pointer to pointer of device, used to retrieve a list of devices    libusb_device_handle *dev_handle; //a device handle    libusb_context *ctx = NULL; //a libusb session    int r; //for return values    ssize_t cnt; //holding number of devices in list    r = libusb_init(&ctx); //initialize the library for the session we just declared     if(r < 0) {        cout<<"Init Error "<<r<<endl; //there was an error        return 1;    }    libusb_set_debug(ctx, 3); //set verbosity level to 3, as suggested in the documentation     cnt = libusb_get_device_list(ctx, &devs); //get the list of devices    if(cnt < 0) {        cout<<"Get Device Error"<<endl; //there was an error        return 1;    }    cout<<cnt<<" Devices in list."<<endl;     dev_handle = libusb_open_device_with_vid_pid(ctx, 5118, 7424); //these are vendorID and productID I found for my usb device    if(dev_handle == NULL)        cout<<"Cannot open device"<<endl;    else        cout<<"Device Opened"<<endl;    libusb_free_device_list(devs, 1); //free the list, unref the devices in it     unsigned char *data = new unsigned char[4]; //data to write    data[0]='a';data[1]='b';data[2]='c';data[3]='d'; //some dummy values     int actual; //used to find out how many bytes were written    if(libusb_kernel_driver_active(dev_handle, 0) == 1) { //find out if kernel driver is attached        cout<<"Kernel Driver Active"<<endl;        if(libusb_detach_kernel_driver(dev_handle, 0) == 0) //detach it            cout<<"Kernel Driver Detached!"<<endl;    }    r = libusb_claim_interface(dev_handle, 0); //claim interface 0 (the first) of device (mine had jsut 1)    if(r < 0) {        cout<<"Cannot Claim Interface"<<endl;        return 1;    }    cout<<"Claimed Interface"<<endl;     cout<<"Data->"<<data<<"<-"<<endl; //just to see the data we want to write : abcd    cout<<"Writing Data..."<<endl;    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    if(r == 0 && actual == 4) //we wrote the 4 bytes successfully        cout<<"Writing Successful!"<<endl;    else        cout<<"Write Error"<<endl;     r = libusb_release_interface(dev_handle, 0); //release the claimed interface    if(r!=0) {        cout<<"Cannot Release Interface"<<endl;        return 1;    }    cout<<"Released Interface"<<endl;     libusb_close(dev_handle); //close the device we opened    libusb_exit(ctx); //needs to be called to end the     delete[] data; //delete the allocated memory for data    return 0;}

結尾:這個教程對於這個話題來說是十分簡單的介紹,需要時間需聯絡同步傳輸,然後移動是非同步,這還有很多需要學習。
希望這些對你的初學有協助。


原文串連:http://blog.cnnbboy.com/?p=313

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.