玩轉USB HID系列:libusb函數介紹

寫在前面

本文轉載自https://blog.csdn.net/wince_lover/article/details/70337809
這篇文章可謂是酣暢淋漓又言簡意賅,佩服佩服,
在此轉載爲了玩轉USB系列的學習完整性,無任何其它含義!

1 libusb_init

1 libusb_init
函數原型:int libusb_init(libusb_context **ctx);
功能說明:該函數進行libusb的初始化,必須最先調用。
參數說明:ctx通常設置NULL
返回值:0成功,非0 失敗

2 libusb_exit

2 libusb_exit
函數原型:void libusb_exit(libusb_context *ctx);
功能說明:和libusb_init成對使用,釋放相應的資源。
參數說明:ctx通常設置NULL

3 libusb_has_capability

3 libusb_has_capability
函數原型:int libusb_has_capability(uint32_t capability);
功能說明:判斷當前的庫是否支持某項功能
參數說明:capability的取值範圍在 enum libusb_capability中定義。
LIBUSB_CAP_HAS_CAPABILITY libus庫的 API是否有效,該項通常總是返回1
LIBUSB_CAP_HAS_HOTPLUG 是否支持熱插拔
LIBUSB_CAP_HAS_HID_ACCESS 是否支持訪問HID設備,而不需要用戶干預
LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER 是否支持在內核中釋放默認的驅動也就是可以調用libusb_detach_kernel_driver來釋放內核驅動
返回值:非0 支持 ,0 不支持

4 libusb_hotplug_register_callback

4 libusb_hotplug_register_callback
函數原型:int LIBUSB_CALL libusb_hotplug_register_callback(libusb_context *ctx, libusb_hotplug_event events,libusb_hotplug_flag flags, int vendor_id, int product_id,
int dev_class, libusb_hotplug_callback_fn cb_fn, void *user_data,libusb_hotplug_callback_handle *handle);
功能說明:註冊回調函數,響應熱插拔事件。
參數說明:ctx 通常爲NULL
events 要響應的事件,參數爲LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED設備插入事件 LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT 設備拔出事件,也可以LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED|LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT表示同時響應插拔事件
flags 如果爲0,只有發生插拔的時候纔會調用註冊的回調函數,如果爲LIBUSB_HOTPLUG_ENUMERATE,則在初始化前設備已經插入,也會調用註冊的毀掉函數。
vendor_id 需要監控的VID,只有指定的VID的設備插拔,纔會調用回調函數 。設置爲LIBUSB_HOTPLUG_MATCH_ANY,則不判斷VID
product_id 需要監控的PID,如果設置爲LIBUSB_HOTPLUG_MATCH_ANY,則不判斷PID
dev_class 需要監控的設備class,如果設置爲LIBUSB_HOTPLUG_MATCH_ANY,則不判斷class。注意這裏的class是與libusb_device_descriptor的class匹配,而不是 libusb_interface_descriptor的class
cb_fn 回調函數的指針 回調函數的定義爲int LIBUSB_CALL hotplug_callback(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data)
user_data 用戶數據的指針 對應回調函數中的user_data
handle 句柄
返回值:0成功,非0 失敗
注意:不要在回調函數中調用可能阻塞的操作,否則可能造成libusb的其他函數執行失敗,不要在回調函數中調用libusb_claim_interface等操作,有可能會失敗

5 libusb_hotplug_deregister_callback

5 libusb_hotplug_deregister_callback
函數原型:void LIBUSB_CALL libusb_hotplug_deregister_callback(libusb_context *ctx,libusb_hotplug_callback_handle handle);
參數說明:註銷libusb_hotplug_register_callback函數註冊的回調函數
參數說明:ctx 通常爲NULL
handle libusb_hotplug_register_callback返回的句柄
返回值:無

6 libusb_handle_events

6 libusb_handle_events
函數原型: int LIBUSB_CALL libusb_handle_events(libusb_context *ctx);
功能說明:在阻塞模式中處理任何掛起的事件。
參數說明:ctx 通常爲NULL
返回值:0成功,非0 失敗
注意:1調用libusb_handle_events的線程,不要執行阻塞的操作,否則可能造成libusb其他函數執行失敗
2 如果註冊了熱插拔事件,必須要在循環中調用這個函數 例如下面的代碼如論怎麼插拔USB設備,都不會打印“device insert”
static int LIBUSB_CALL hotplug_callback(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data)
{
printf(“device insert \n”);
}
int main(int argc, char **argv)
{
libusb_hotplug_callback_handle hp;
libusb_init (NULL);
libusb_hotplug_register_callback (NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, LIBUSB_HOTPLUG_ENUMERATE, LIBUSB_HOTPLUG_MATCH_ANY,
LIBUSB_HOTPLUG_MATCH_ANY, 0, hotplug_callback, NULL, &hp);
while(1);
libusb_hotplug_deregister_callback(hp);
}
必須要改爲下面的代碼,插拔USB纔會有“device insert” 的信息
static int LIBUSB_CALL hotplug_callback(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data)
{
printf(“device insert \n”);
}
int main(int argc, char **argv)
{
libusb_hotplug_callback_handle hp;
libusb_init (NULL);
libusb_hotplug_register_callback (NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, LIBUSB_HOTPLUG_ENUMERATE, LIBUSB_HOTPLUG_MATCH_ANY,
LIBUSB_HOTPLUG_MATCH_ANY, 0, hotplug_callback, NULL, &hp);
while(1)
{
libusb_handle_events(NULL);
}
libusb_hotplug_deregister_callback(hp);
}

7 libusb_open_device_with_vid_pid

7 libusb_open_device_with_vid_pid
函數原型:libusb_device_handle * LIBUSB_CALL libusb_open_device_with_vid_pid( libusb_context *ctx, uint16_t vendor_id, uint16_t product_id);
函數功能:通過VID和PID打開一個USB 設備,並返回設備句柄libusb_device_handle的指針
參數說明:ctx 通常爲NULL
vendor_id 設備的VID
product_id 設備的PID
返回值:成功返回libusb_device_handle的指針 ,失敗返回NULL

8 libusb_open

8 libusb_open
函數原型:int LIBUSB_CALL libusb_open(libusb_device *dev, libusb_device_handle **handle);
函數功能:通過libusb_device的指針打開一個USB設備,並返回設備句柄libusb_device_handle的指針
參數說明:dev libusb_device的指針
handle 用來返回設備句柄libusb_device_handle的指針
返回值:0成功,非0 失敗

9 libusb_close

9 libusb_close
函數原型:void LIBUSB_CALL libusb_close(libusb_device_handle *dev_handle);
函數功能:關閉 libusb_open或者libusb_open_device_with_vid_pid打開的設備
參數說明:dev_handle 調用libusb_open或者libusb_open_device_with_vid_pid返回的設備句柄libusb_device_handle的指針
返回值: 無

10 libusb_get_device_list

10 libusb_get_device_list
函數原型:ssize_t LIBUSB_CALL libusb_get_device_list(libusb_context *ctx, libusb_device ***list);
函數功能:獲取當前的設備列表
函數功能:ctx 通常爲NULL
list USB設備列表
返回值:0成功,非0 失敗

11 libusb_free_device_list

11 libusb_free_device_list
函數原型:void LIBUSB_CALL libusb_free_device_list(libusb_device **list, int unref_devices);
函數功能:釋放以前使用的設備列表
參數說明:list 要釋放的設備列表的指針
unref_devices 如果該參數置1 列表中的每個設備的引用計數減1
返回值:無
注:下面是示例代碼:
libusb_device **devs;
ssize_t cnt;
int i;
libusb_init (NULL);
cnt = libusb_get_device_list(NULL, &devs);
for(i=0;i<cnt;i++)
{
PrintUsbDec(devs[i]);
}
libusb_free_device_list(devs, 1);

12 libusb_get_device_descriptor

12 libusb_get_device_descriptor
函數原型:int LIBUSB_CALL libusb_get_device_descriptor(libusb_device *dev, struct libusb_device_descriptor *desc);
函數功能:獲取USB設備的設備描述符
參數說明:dev libusb_device的指針,是要讀取的設備
desc 設備描述符的指針,用來帶回設備描述符的結構
返回值:0成功,非0 失敗
注意:這個函數是將設備描述符的結構拷貝到desc指向的地址
所以,下面的用法是錯誤的
struct libusb_device_descriptor *desc;
libusb_get_device_descriptor(dev,desc);
正確的寫法是
struct libusb_device_descriptor desc;
libusb_get_device_descriptor(dev,&desc);

13 libusb_get_config_descriptor

13 libusb_get_config_descriptor
函數原型:int LIBUSB_CALL libusb_get_config_descriptor(libusb_device *dev, uint8_t config_index, struct libusb_config_descriptor **config);
函數功能:獲取指定設備的配置描述符
參數說明:dev libusb_device的指針,是要讀取的設備
config_index 配置描述符的索引(一個USB設備可能有多個配置)
config 配置描述符的指針,用來帶回設備描述符
返回值:0成功,非0 失敗

14 libusb_free_config_descriptor

14 libusb_free_config_descriptor
函數原型:void LIBUSB_CALL libusb_free_config_descriptor( struct libusb_config_descriptor *config);
函數功能:釋放配置描述符
參數說明:config 要釋放的配置描述符
返回值:無
注意: 用libusb_get_config_descriptor獲取配置描述符後必須要調用 libusb_free_config_descriptor釋放,否則會造成內存泄漏。

15 libusb_control_transfer

函數原型:int LIBUSB_CALL libusb_control_transfer(libusb_device_handle *dev_handle, uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
unsigned char *data, uint16_t wLength, unsigned int timeout);
參數說明:dev_handle libusb_device_handle的指針
request_type D7=0主機到設備, =1設備到主機;
D6D5 =00標準請求命令, 01 類請求命令,10用戶定義的命令,11保留值
D4D3D2D1D0= 0表示接收者爲設備,1表示接收者爲接口,2表示接收者爲端點,3表示接收者爲其他,其他值保留
這個參數由 enum libusb_request_recipient 、enum libusb_request_type 、enum libusb_endpoint_direction 組合
bRequest 命令的序號(其實就是命令);所有的命令都是以不同編碼值的方式傳遞給設備的,bRequest就表示USB命令的編碼值。可以是USB標準命令,也可以用戶自定義命令
標準請求命令定義在 enum libusb_standard_request
Value 2個字節,用來傳送當前請求的參數,隨請求不同而變。
Index 索引字段同樣是2個字節,描述的是接口號
data 要傳輸的數據的指針,不需要傳輸數據,設置爲NULL
wLength 數據的長度。當命令不需要傳輸數據時,此字段設爲0
timeout 設置超時的毫秒數,如果設置0,則永不超時
注:USB標準請求命令:
1.獲取狀態 Get Status (00H)
A:[To Device]獲取設備的狀態:
*.位0:自供電(0表示總線供電;1表示自供電).
*.位1:遠程喚醒(0表示不支持遠程喚醒;1表示遠程喚醒).
*.位2~15:保留.
*.一般選擇總線供電,不支持遠程喚醒,所以返回數據就是0x0000.
B:[To Interface]獲取接口的狀態:
*.接口狀態的16位字節全部保留,所以返回數據就是0x0000.
C:[To Endpoint]獲取端點的狀態:
*.位0:Halt(0表示端點允許;1表示端點禁止).
*.位1~15:保留(復位爲0).
2.清除特性 Clear Feature (01H)
A:[To Device]清除設備的遠程喚醒功能,並返回一個空包.
B:[To Endpoint]解禁端點.
3.設置特性 Set Feature (03H)
A:[To Device]設置設備的遠程喚醒功能,並返回一個空包.
B:[To Endpoint]禁止端點.
4.設置地址 Set Address (05H)
A:設置設備地址.
5.獲取描述符 Get Descriptor (06H)
A:[To Device]獲取設備描述符:
*.描述當前USB協議的版本號.設備端點0的FIFO大小.USB設備的ID號等.
B:[To Configuration]獲取配置描述符:
*.描述USB設備接口個數及是否有自供電能力等.
C:[To Interface]獲取接口描述符:
*.描述端點0以外的物理端點個數等信息.
D:[To Endpoint]獲取端點描述符:
*.描述端點0各端點的傳輸類型和最大信息包大小和端點的傳輸方向(IN/OUT).
6.設置描述符(可選,無法更新) Set Descriptor (07H)
7.獲取配置信息 Get Configuration (08H)
8.設置配置 Set Configuration (09H)
A:[To Configuration]設置配置描述符.
B:[To Interface]設置接口描述符.
C:[To Endpoint]設置端點描述符.
9.獲取接口信息 Get Interface (0AH)
10.設置接口 Set Interface (0BH)
11.SYNCH_FRAME(0CH)
用於設備設置和報告一個端點的同步幀.

16 libusb_kernel_driver_active

16 libusb_kernel_driver_active
函數原型:int LIBUSB_CALL libusb_kernel_driver_active(libusb_device_handle *dev,int interface_number);
函數功能:確定指定接口的內核驅動程序是否已經激活。如果一個內核驅動程序是激活的,libusb_claim_interface調用的會失敗
參數說明:dev 調用 libusb_open或者libusb_open_device_with_vid_pid返回的libusb_device_handle的句柄
interface_number 接口號,這個對應接口描述符的 bInterfaceNumber
返回值:1 已經激活,非1 沒有激活

17 libusb_detach_kernel_driver

17 libusb_detach_kernel_driver
函數原型:int LIBUSB_CALL libusb_detach_kernel_driver(libusb_device_handle *dev,int interface_number);
函數功能:卸載指定接口的內核驅動程序。如果一個內核驅動程序是激活的,必須先調用這個函數,再調用libusb_claim_interface
參數說明:dev 調用 libusb_open或者libusb_open_device_with_vid_pid返回的libusb_device_handle的句柄
interface_number 接口號,這個對應接口描述符的 bInterfaceNumber
返回值:0 成功,非0失敗

18 libusb_claim_interface

18 libusb_claim_interface
函數原型:int LIBUSB_CALL libusb_claim_interface(libusb_device_handle *dev, int interface_number);
函數功能:爲指定的設備申請接口
參數說明:dev 調用 libusb_open或者libusb_open_device_with_vid_pid返回的libusb_device_handle的句柄
interface_number 接口號,這個對應接口描述符的 bInterfaceNumber
返回值:0 成功,非0失敗

19 libusb_release_interface

19 libusb_release_interface
函數原型:int LIBUSB_CALL libusb_release_interface(libusb_device_handle *dev, int interface_number);
函數功能:釋放之前爲指定的設備申請接口,注意這個函數只是釋放接口,不會重新加載內核驅動
參數說明:dev 調用 libusb_open或者libusb_open_device_with_vid_pid返回的libusb_device_handle的句柄
interface_number 接口號,這個對應接口描述符的 bInterfaceNumber
返回值:0 成功,非0失敗

19 libusb_attach_kernel_driver

19 libusb_attach_kernel_driver
函數原型:int LIBUSB_CALL libusb_attach_kernel_driver(libusb_device_handle *dev, int interface_number);
函數功能:加載指定接口的內核驅動
參數說明:dev 調用 libusb_open或者libusb_open_device_with_vid_pid返回的libusb_device_handle的句柄
interface_number 接口號,這個對應接口描述符的 bInterfaceNumber
返回值:0 成功,非0失敗

下面是示例代碼:
if(libusb_kernel_driver_active(handle, bInterfaceNumber) == 1) //判斷內核驅動時候加載
{
if(libusb_detach_kernel_driver(handle, bInterfaceNumber) == 0) //卸載驅動,例如我們操作的是一個U盤,那麼執行到這裏設備文件裏面的U盤將消失
{
printf(“Kernel Driver Detached!”);
}
}
libusb_claim_interface(handle, bInterfaceNumber);
…對設備進行讀寫操作
libusb_release_interface(handle, bInterfaceNumber); //釋放請求的接口

libusb_attach_kernel_driver(handle, bInterfaceNumber); //加載內核驅動,U盤將重新出現在設備文件裏

20 libusb_set_auto_detach_kernel_driver

20 libusb_set_auto_detach_kernel_driver
函數原型:int LIBUSB_CALL libusb_set_auto_detach_kernel_driver( libusb_device_handle *dev, int enable);
函數功能:設置自動卸載內核驅動,注意這個函數調用時不會卸載內核驅動,只是做標記。在調用libusb_claim_interface的時候卸載內核驅動
在調用libusb_release_interface的時候自動加載內核驅動
參數說明:dev 調用 libusb_open或者libusb_open_device_with_vid_pid返回的libusb_device_handle的句柄
enable 1 使能自動卸載的功能,0關閉
返回值:0 成功,非0失敗
例如 下面的代碼和上面的代碼效果等同
libusb_set_auto_detach_kernel_driver(handle,1);
libusb_claim_interface(handle, bInterfaceNumber); //請求接口之前先卸載內核驅動
…對設備進行讀寫操作
libusb_release_interface(handle, bInterfaceNumber); //釋放請求的接口後自動加載內核驅動

21 libusb_bulk_transfer

21 libusb_bulk_transfer
函數原型:int LIBUSB_CALL libusb_bulk_transfer(libusb_device_handle *dev_handle,unsigned char endpoint, unsigned char *data, int length,int *actual_length, unsigned int timeout);
函數功能:執行USB批量傳輸。該函數可以處理輸入和輸出,根據端點地址的方向位推斷傳輸方向,該函數採用同步模式,數據傳輸完畢才返回
參數說明:dev_handle 調用 libusb_open或者libusb_open_device_with_vid_pid返回的libusb_device_handle的句柄
endpoint 端點地址 最高位爲1表示輸入
data 發送或者接收緩衝區指針
length 緩衝區長度
actual_length 帶回實際傳輸長度
timeout 超時的毫秒數,0 永不超時
返回值:0 成功,非0失敗

22 libusb_clear_halt

22 libusb_clear_halt
函數原型:int LIBUSB_CALL libusb_clear_halt(libusb_device_handle *dev, unsigned char endpoint);
函數功能:清除端點的halt/stall狀態,libusb_bulk_transfer有可能返回LIBUSB_ERROR_PIPE,這是需要調用這個函數
參數說明:dev 調用 libusb_open或者libusb_open_device_with_vid_pid返回的libusb_device_handle的句柄
endpoint 出錯的端點地址
返回值:0 成功,非0失敗

23 libusb_interrupt_transfer

23 libusb_interrupt_transfer
函數原型:int LIBUSB_CALL libusb_interrupt_transfer(libusb_device_handle *dev_handle,unsigned char endpoint, unsigned char *data, int length,int *actual_length, unsigned int timeout);
函數功能:執行USB中斷傳輸。該函數可以處理輸入和輸出,根據端點地址的方向位推斷傳輸方向,該函數採用同步模式,數據傳輸完畢才返回
參數說明:dev_handle 調用 libusb_open或者libusb_open_device_with_vid_pid返回的libusb_device_handle的句柄
endpoint 端點地址 最高位爲1表示輸入
data 發送或者接收緩衝區指針
length 緩衝區長度
actual_length 帶回實際傳輸長度
timeout 超時的毫秒數,0 永不超時
返回值:0 成功,非0失敗

24 libusb_set_configuration

24 libusb_set_configuration
函數原型:int LIBUSB_CALL libusb_set_configuration(libusb_device_handle *dev,int configuration);
函數功能:爲設備設置一個配置參數,大部分設備只有一個配置這個函數通常不需要調用。當某個USB設備有多個配置的時候需要設置
參數說明:dev 調用 libusb_open或者libusb_open_device_with_vid_pid返回的libusb_device_handle的句柄
configuration 配置參數,這個對應的是配置描述符裏面的bConfigurationValue
返回值:0 成功,非0失敗

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章