本文檔描述libusb的API,以及如何開發USB應用。
1 介紹c++
1.1 概覽
本文檔描述libusb-0.1的API和USB相關內容。
1.2 當前OS支持
Linux 2.2或以上
FreeBSD/NetBSD/OpenBSD
Darwin/MacOSX
2 API異步
2.1 設備與接口
一個設備可能有多個接口,因此一個句柄能夠返回多個接口實例。不要忘記調用 usb_claim_interface() 。
2.2 超時
老是以毫秒爲單位。
2.3 數據類型
同時使用有抽象結構和非抽象結構來保持可移植性。
2.4 同步
全部libusb v0.1的函數都是同步的,這意味着操做完成或超時前不會返回。異步操做從libusb v1.0開始支持。
2.5 返回值
libusb v0.1有兩種返回值。一種是 usb_open() 返回的句柄,另外一種是整數int,返回負數表示錯誤。
3 函數函數
3.1 核心函數
void usb_init(void);
初始化libusb。
int usb_find_busses(void);
查找全部總線,返回上次調用之後改變的數量(包括新增的和移除的總線)。
int usb_find_devices(void);
尋找每一個總線上的全部設備。應該在 usb_find_busses() 以後調用。返回上次調用後改變的數量(包括新增和移除的設備)。
struct usb_bus *usb_get_busses(void);
簡單的返回全局變量 usb_busses 。這僅對支持C調用規範和可使用共享庫的語言,可是不支持C全局變量的(例如Delphi)。
3.2 設備操做
這組函數用於操做設備。容許你打開關閉設備,設置配置、輪換設置、乾淨的關閉和重置設備。它也提供OS級別的操做,如認領(claim)和釋放接 口。
usb_dev_handle *usb_open(struct *usb_device dev);
打開設備以供使用,返回設備句柄。
int usb_close(usb_dev_handle *dev);
關閉設備,返回0成功,負數失敗。
int usb_set_configuration(usb_dev_handle *dev, int configuration);
設置活躍配置。configuration參數是描述符bConfigurationValue字段的值。返回0成功,負數失敗。
int usb_set_altinterface(usb_dev_handle *dev, int alternate);
設置當前接口的活躍輪換設置。alternate參數是描述符bAlternateSetting字段的值。返回0成功,負數失敗。
int usb_resetep(usb_dev_handle *dev, unsigned int ep);
重置指定端點的全部狀態。ep參數是描述符的bEndpointAddress字段的值。返回0稱公,負數失敗。
該接口不建議使用,你可能須要的是 usb_clear_halt() 。
int usb_clear_halt(usb_dev_handle *dev, unsigned int ep);
清理端點全部中止狀態,ep是描述符bEndpointAddress字段的值。返回0成功,負數失敗。
int usb_reset(usb_dev_handle *dev);
重置指定設備,經過發送RESET指令過去。返回0成功,負數失敗。
在執行該函數以後,須要從新列舉,找到設備。當前的句柄沒法再工做了。
int usb_claim_interface(usb_dev_handle *dev, int interface);
經過OS認領一個接口。interface參數是描述符的bInterfaceNumber字段。返回0成功,負數失敗。
必須在任何接口相關操做(如 usb_set_altinterface() 、 usb_bulk_write() 等)以前調用。
返回碼:
EBUSY :接口無效,沒法被認領
ENOMEM :內存不足
int usb_release_interface(usb_dev_handle *dev, int interface);
釋放以前認領的接口。interface參數是描述符的bInterfaceNumber字段。返回0成功,負數失敗。
3.3 控制傳輸
發送消息到缺省控制管道。
int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout);
發送控制請求到設備的缺省控制管道。參數對應USB規範中的同名類型。返回讀寫字節數,負數失敗。
int usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf, size_t buflen);
獲取設備的字符串描述,經過index和langdi索引。返回Unicode字符串到buf中。返回實際寫入buf的字節數,負數失敗。
int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf, size_t buflen);
包裝了 usb_get_string() 函數,返回第一種語言指定index索引的字符串描述,並轉換到C風格的ASCII。返回寫入buf字節數,負數失敗。
int usb_get_descriptor(usb_dev_handle *dev, unsigned char type, unsigned char index, void *buf, int size);
獲取設備缺省控制管道的描述符,經過type和index索引。返回實際寫入buf的字節數,負數失敗。
參考 usb_get_descriptor_by_endpoint() 瞭解容許指定控制端點的。
int usb_get_descriptor_by_endpoint(usb_dev_handle *dev, int ep, unsigned char type, unsigned char index, void *buf, int size);
從設備獲取描述符,以type和index索引,以ep標誌的控制管道。返回讀取字節數,負數失敗。
3.4 塊傳輸
這部分容許應用從數據塊管道發送和接收數據。
int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);
寫入一塊數據到端點ep,返回寫入成功字節數,負數失敗。
int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);
讀取一塊數據,從端點ep,返回讀取成功字節數,負數失敗。
3.5 中斷傳輸
這組函數容許應用發送和接收數據經過中斷管道。
int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);
執行對端點ep的中斷寫入,返回實際寫入字節數,負數失敗。
int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);
執行對中斷端點ep的讀取,返回實際讀取字節數,負數失敗。
3.6 不可移植
這些函數是不可移植的。有些是暴露了OS USB API之類的。他們都回加上函數名後綴 _np 。
一個C預處理器宏會定義實現的函數。形式是 LIBUSB_HAS_ 加上函數名,沒有 usb_ 前綴。例如, usb_get_driver_np() 實現了,就會定義 LIBUSB_HAS_GET_DRIVER_NP 。
int usb_get_driver_np(usb_dev_handle *dev, int interface, char *name, int namelen);
這個函數獲取接口驅動的名字。成功返回0,失敗負數。
只在Linux有實現。
int usb_detach_kernel_driver_np(usb_dev_handle *dev, int interface);
這個函數從接口剝離內核驅動。使用了libusb的應用能夠隨即從新認領接口。返回0成功,負數失敗。
只在Linux有實現。
4 例子code
4.1 簡單例子
與設備通訊前要先找到它。須要先找到全部總線(busses),而後找到全部設備:
struct usb_bus *busses;索引
usb_init();
usb_find_busses();
usb_find_devices();接口
busses=usb_get_busses();
在這以後,應用應該手動輪詢全部總線和設備,匹配其所要的:
struct usb_bus *bus;
int c,i,a;ip
for (bus=busses; bus; bus=bus->next) {
struct usb_device *dev;
for (dev=bus->devices; dev; dev=dev->next) {
if (dev->descriptor.bDeviceClass==7) {
/*打開設備,認領接口,而後操做*/
}
/*循環遍歷全部配置*/
for (c=0; c< dev->descriptor.bNumConfigurations; c++) {
/*循環遍歷全部接口*/
for (i=0; i< dev->config[c].bNumInterfaces; i++) {
/*循環遍歷全部輪換設置*/
for (a=0; a< dev->config[c].interface[i].num_altsetting; a++) {
/*檢查接口是不是打印機*/
if (dev->config[c].interface[i].altsetting[a].bInterfaceClass==7) {
/*打開設備,設置輪換配置,認領接口,而後操做*/
}
}
}
}
}
}
4.2 源碼包的例子
tests目錄有個程序叫 testlibusb.c 。它簡單的調用libusb尋找全部設備,而後遍歷並打印描述符。其結果很簡單,不過用處有限。卻是能夠做爲很好的入門。
4.3 其餘應用
其餘應用就參考其餘的項目吧:
gPhoto :使用libusb與相機通訊
rio500 :使用libusb與SONICblue Rio 500播放器內存