libusb库学习

libusb是一个使用C编写的库,它提供USB设备的通用的访问方法。APP通过它,可以方便地访问USB设备,无需编写USB设备驱动程序。

libusb源码的移植

通过网址下载源码https://github.com/libusb/libusb/releases,之后进行交叉编译。

1
./configure --host=arm-linux --disable-udev --prefix=/home/moss/linux/tool/libusb --CC=arm-linux-gnueabihf-gcc

配置完成后就可以进行编译了,

1
2
make
make install

之后可以发现生成了libusb.h文件,但是缺少里面调用的usb.h文件,所以需要将usbcompat的源码包进行交叉编译。

下载usbcompat源码包

1
./configure --host=arm-linux --disable-udev --prefix=/home/moss/linux/tool/libusb --CC=arm-linux-gnueabihf-gcc

配置完以后进行编译

1
2
3
sudo  -i
make
make install

用法

libusb: 应用程序编程接口 (sourceforge.io)

libusb封装了更好用的函数,这些函数的使用可以分为5个步骤:

初始化
打开设备
移除原驱动/认领接口
传输
关闭设备

设备枚举

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
43
44
45
46
47
48
49
50
51
ssize_t 	libusb_get_device_list (libusb_context *ctx, libusb_device ***list)
//返回当前连接到系统的 USB 设备列表。 这是查找要操作的 USB 设备的入口点。
void libusb_free_device_list (libusb_device **list, int unref_devices)
//释放先前使用 libusb_get_device_list() 发现的设备列表。 如果设置了 unref_devices 参数,则列表中每个设备的引用计数减 1。
uint8_t libusb_get_bus_number (libusb_device *dev)
//获取设备连接的总线编号。
uint8_t libusb_get_port_number (libusb_device *dev)
//获取设备连接的端口号。
int libusb_get_port_numbers (libusb_device *dev, uint8_t *port_numbers, int port_numbers_len)
//获取指定设备的从根节点开始的所有端口号列表
int libusb_get_port_path (libusb_context *ctx, libusb_device *dev, uint8_t *port_numbers, uint8_t port_numbers_len)
uint8_t libusb_get_device_address (libusb_device *dev)
//获取设备在它所连接的总线上的地址。
int libusb_get_device_speed (libusb_device *dev)
//获取设备的协商连接速度,返回码见 libusb_speed。
int libusb_get_max_packet_size (libusb_device *dev, unsigned char endpoint)
//获取特定端点的 wMaxPacketSize 值。
int libusb_get_max_iso_packet_size (libusb_device *dev, unsigned char endpoint)
//基于端点描述符中的 wMaxPacketSize 字段,计算特定端点在 1 个微帧的持续时间内能够发送或接收的最大数据包大小。
void libusb_unref_device (libusb_device *dev)
//减少设备的引用计数。 如果递减操作导致引用计数达到零,则设备将被销毁。
int libusb_wrap_sys_device (libusb_context *ctx, intptr_t sys_dev, libusb_device_handle **dev_handle)
(不常用,略)
int libusb_open (libusb_device *dev, libusb_device_handle **dev_handle)
//打开设备并获取设备句柄。 句柄允许您在相关设备上执行 I/O。
void libusb_close (libusb_device_handle *dev_handle)
//关闭设备句柄。 应在应用程序退出之前在所有打开的句柄上调用。
libusb_device * libusb_get_device (libusb_device_handle *dev_handle)
//获取设备句柄关联的 libusb_device 底层设备。
int libusb_get_configuration (libusb_device_handle *dev_handle, int *config)
//确定当前活动配置的 bConfigurationValue。
int libusb_set_configuration (libusb_device_handle *dev_handle, int configuration)
//设置设备的活动配置。这在支持多个配置的USB设备中会用到。
int libusb_claim_interface (libusb_device_handle *dev_handle, int interface_number)
//在给定的设备句柄上声明一个接口。 您必须先声明要使用的接口,然后才能在其任何端点上执行 I/O。
int libusb_release_interface (libusb_device_handle *dev_handle, int interface_number)
//释放先前使用 libusb_claim_interface() 声明的接口。 您应该在关闭设备句柄之前释放所有声明的接口。
int libusb_set_interface_alt_setting (libusb_device_handle *dev_handle, int interface_number, int alternate_setting)
//激活接口的备用设置。 该接口必须先前已使用 libusb_claim_interface() 声明。
int libusb_clear_halt (libusb_device_handle *dev_handle, unsigned char endpoint)
//清除端点的暂停/停止条件。 处于停止状态的端点无法接收或发送数据,直到停止条件停止。
int libusb_reset_device (libusb_device_handle *dev_handle)
//执行 USB 复位以重新初始化设备。
int libusb_kernel_driver_active (libusb_device_handle *dev_handle, int interface_number)
//确定内核驱动程序是否在接口上处于活动状态。 如果内核驱动程序处于活动状态,则不能声明该接口,并且 libusb 将无法执行 I/O。
int libusb_detach_kernel_driver (libusb_device_handle *dev_handle, int interface_number)
//分离接口和内核驱动程序。 如果成功,您将能够声明接口并执行 I/O。
int libusb_attach_kernel_driver (libusb_device_handle *dev_handle, int interface_number)
//重新附加接口的内核驱动程序,该驱动程序之前使用 libusb_detach_kernel_driver() 分离。
int libusb_set_auto_detach_kernel_driver (libusb_device_handle *dev_handle, int enable)
//启用/禁用 libusb 的自动内核驱动程序分离。 启用此功能后,libusb 将在声明接口时自动分离接口上的内核驱动程序,并在释放接口时附加它。

同步传输

1
2
3
4
5
6
7
8
9
10
void 	libusb_set_debug (libusb_context *ctx, int level)
//设置libusb调试等级,方便查看调试过程和log信息。
void libusb_set_log_cb (libusb_context *ctx, libusb_log_cb cb, int mode)
//设置log处理程序,libusb 会将其日志消息重定向到提供的回调函数。
int libusb_set_option (libusb_context *ctx, enum libusb_option option,...)
//设置库选项,使用此函数可配置库中的特定选项。
int libusb_init (libusb_context **context)
//初始化 libusb。 必须在调用任何其他 libusb 函数之前调用此函数。
void libusb_exit (libusb_context *ctx)
//取消初始化 libusb。 应在关闭所有打开的设备后和应用程序终止之前调用。

异步传输

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
43
struct libusb_transfer * libusb_alloc_transfer(int	iso_packets)
/*使用指定数量的常时等量数据包描述符分配 libusb 传输,不用时候使用libusb_free_transfer释放
iso_packets参数为分配时候常时等量数据包描述符的数量,
返回值:分配流数或失败的error码*/
void libusb_free_transfer(struct libusb_transfer *)
/*释放传输结构*/
int libusb_submit_transfer(struct libusb_transfer *)
/*触发usb传输,后立即返回
返回值:0成功,不同失败返回不同error码*/
int libusb_cancel_transfer(struct libusb_transfer *)
/*异步取消以前提交的传输
返回值:0成功,失败时的LIBUSB_ERROR代码*/
uint32_t libusb_transfer_get_stream_id(struct libusb_transfer *)
/*获取传输批量流ID
返回值:传输的流ID*/
*libusb_control_transfer_get_data(struct libusb_transfer *)
/*获取控制传输的数据部分,
返回指:向数据部分的第一个字节的指针*/
unsigned char *libusb_control_transfer_get_setup(const struct libusb_transfer *transfer);
/*获取控制传输的控制设置数据包*,
返回值:指向传输数据缓冲区开头的强制转换指针*/
void libusb_fill_bulk_transfer(struct libusb_transfer *transfer,
libusb_device_handle *dev_handle,
unsigned char endpoint,
unsigned char *buffer,
int length,
libusb_transfer_cb_fn callback,
void *user_data,
unsigned int timeout);
/*transfer:指向要填充的 transfer 结构体的指针。
dev_handle:指向已打开设备的设备句柄。
endpoint:要使用的端点地址。
buffer:指向数据缓冲区的指针。
length:要传输的数据长度。
callback:传输完成后要调用的回调函数。
user_data:传递给回调函数的用户数据指针。
timeout:传输超时时间,以毫秒为单位,0 表示无限等待。*/
int libusb_handle_events_timeout(libusb_context *ctx, struct timeval *tv)
/*该函数用于处理USB事件,包括设备插拔、传输完成等。该函数会阻塞当前线程,
直到事件处理完成或超时。参数ctx为libusb的上下文,参数tv为超时时间,如果为NULL则表示无限等待。*/
int libusb_handle_events(libusb_context *ctx)
/*该函数用于处理USB事件,类似于libusb_handle_events_timeout函数,但是没有超时限制,
会一直阻塞当前线程直到事件处理完成。参数ctx为libusb的上下文。*/