0%

libusb的使用

本文仅从libusb api-1.0版本的使用方面解读,不详细介绍usb的基本知识和传输协议。

libusb简介

libusb 是一个用来访问usb设备的应用库,可以跨平台使用,支持Linux、Mac、Windows等主流操作系统,当然Andorid上也有libusb身影。

libusb相关网站:

github: https://github.com/libusb/libusb

homepage: https://libusb.info/

api-1.0: http://libusb.sourceforge.net/api-1.0/

当产品需要添加自定义协议时,以hid协议为例,usb的固件代码比较容易实现。与此同时,主机也需要对应的协议来正确解析,这里通常有2种实现方式,第一种是在主机编写usb设备驱动解析协议,另一种是应用通过libusb解析协议,显然后一种方法更通用。

api

初始化

libusb_init
必须最先被执行,完成libusb的初始化。libusb_context代表libusb的会话,如果参数为NULL,会默认创建一个。

1
int libusb_init(libusb_context** context);

libusb_exit
取消libusb初始化,通常在程序结束时调用。

1
void libusb_exit(struct libusb_context* ctx)

设备操作

libusb_open
打开usb设备,获取设备句柄dev_handle。

1
int libusb_open(libusb_device *dev, libusb_device_handle **dev_handle);

libusb_open_device_with_vid_pid
方便快速打开对应pid/vid的设备,可以指定libusb会话。

1
2
libusb_device_handle* libusb_open_device_with_vid_pid(libusb_context *ctx, 
unit16_t vendor_id, uint16_t product_id);

libusb_close
指定设备句柄关闭设备,在程序完成前调用。

1
void libusb_close(libusb_device_handle *dev_handle);

libusb_get_device_list
获得系统当前所有的usb设备的列表

1
ssize_t libusb_get_device_list(libusb_context *ctx, libusb_device ***list);

libusb_free_device_list
释放前面使用的设备列表

1
void libusb_free_device_list(libusb_device **list, int unref_devices)

libusb_get_configuration
获得当前设备的配置模式,usb设备可能包含多个配置

1
int usb_get_configuration(libusb_device_handle *dev_handle, int *config);

libusb_set_configuration
重新设置usb设备的配置模式

1
int usb_set_configuration(libusb_device_handle *dev_handle, int configuration);

libusb_claim_interface
获得usb设备对应接口的所有权

1
int libusb_claim_interface(libusb_device_handle *dev_handle, int interface_number);

libusb_release_interface
释放获取usb设备接口的所有权

1
int libusb_release_interface(libusb_device_handle *dev_handle, int interface_number);

libusb_set_interface_alt_setting
激活某个接口的交替配置

1
int libusb_set_interface_alt_setting(libusb_device_handle *dev_handle, int interface_number, int alternate_config);

数据传输

libusb_control_transfer
控制传输

1
int libusb_control_transfer (libusb_device_handle *dev_handle, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, unsigned char *data, uint16_t wLength, unsigned int timeout);

libusb_bulk_transfer
批量传输

1
int libusb_bulk_transfer (struct libusb_device_handle *dev_handle, unsigned char endpoint, unsigned char *data, int length, int *transferred, unsigned int timeout);

libusb_interrupt_transfer
中断传输

1
int libusb_interrupt_transfer (struct libusb_device_handle *dev_handle, unsigned char endpoint, unsigned char *data, int length, int *transferred, unsigned int timeout);

实例

下面的例子,是打开vid = 1234, pid = 5678的usb设备,同时检查是否有接口0的驱动,如果有直接卸载这个驱动,并获取这个接口的所有权。

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
33
34
35
36
37
38
39
40
41
42
int main(int argc, char *argv[])
{
int ret;
libusb_context *ctx;
libusb_device_handle* handle = NULL; /* handle for USB device */

/* Initialise libusb. */
ret = libusb_init(&ctx);
if (ret != 0)
{
fprintf(stderr, "Error initialising libusb.\n");
return 1;
}

/* Open device with vid and pid */
handle = libusb_open_device_with_vid_pid(0, 1234, 5678);
if (!handle)
{
fprintf(stderr, "Unable to open device.\n");
return 1;
}

/* Check whether a kernel driver is attached to interface #0. If so, we'll
* need to detach it.
*/
if (libusb_kernel_driver_active(handle, 0)) {
ret = libusb_detach_kernel_driver(handle, 0);
if (ret != 0) {
fprintf(stderr, "Error detaching kernel driver.\n");
return 1;
}
}

/* Claim interface #0. */
ret = libusb_claim_interface(handle, 0);
if (ret != 0) {
fprintf(stderr, "Error claiming interface.\n");
return 1;
}

return 0;
}