使用 libusb 与 USB 设备通信
libusb及相关
- libusb是跨平台的USB通信库,官网地址:http://libusb.info/ ,当前版本为1.0,之前的旧版本为0.1
- 如果要兼容旧版本(0.1)的API,可以通过一个兼容层库: libusb-compat-0.1 wrapper https://github.com/libusb/libusb-compat-0.1
- libusb-win32 https://sourceforge.net/p/libusb-win32/wiki/Home/ 是一个单独的项目,目前已停止更新,只做错误修复性的维护。
Windows 驱动
之前的 Toutch T6 的设备驱动,是使用 libusb-win32 制作的,则于签名的问题,安装比较麻烦。
使用 zadig http://zadig.akeo.ie/ ,可以直接安装驱动,也可以更新之前 libusb-win32 制作的驱动。
初始化与注销
正式调用任何 libusb 功能之前,首先需要初始化;
注销之后,就不能再调用任何 libusb 功能了。
初始化使用 libusb_init 方法,注销使用 libusb_exit 方法。
初始化和注销时,可以使用 libusb_context 来管理多个 USB 会话。
初始化之后,使用 libusb_set_option 方法,设置参数(主要是日志级别)
枚举和打开、关闭指定的USB设备
libusb_device 用来表示一个 USB 设备,通过 libusb_get_device_list libusb_get_device_list 函数,可以获得当前连接到系统中的 USB 设备列表。
但是,仅仅有一个设备的引用,并不意味着就可以可以使用该设备,设备可能已被拔出,可能没有权限操作此类设备,或者其他程序或驱动程序可能正在使用该设备。
因此,当找到需要操作的设备时,需要使用 libusb_open 函数来打开设备,如果打开成功,会返回一个设备句柄(一个libusb_device_handle指针),所有的I/O操作,都是在句柄上进行的。
设备发现和引用计数
使用 libusb_get_device_list 获得的设备列表,在使用完后,需要调用 libusb_free_device_list 函数将其释放。同时,列表中的内容(libusb_device)也需要释放。
可以使用 libusb_ref_device 和 libusb_unref_device 方法来增加和减少设备的引用计数,当计数为0时,设备将被销毁。
因此,打开设备的过程应当为:
考虑到上述信息,打开设备的过程可以看作如下:
- 使用libusb_get_device_list()发现设备。
- 选择您想要操作的设备,然后调用libusb_open()。
- Unref查找到的设备列表中的所有设备。
- 释放发现的设备列表。
顺序非常重要!
方便起见,libusb_free_device_list 方法包含一个参数,可以 Unref 列表中的所有设备(即:合并上述的3、4步为一个操作)
另外,libusb_open 实际上对设备增加一个引用计数,而 libusb_close 则减少一个引用计数。
同步 I/O
- libusb_control_transfer
- libusb_bulk_transfer
- libusb_interrupt_transfer
异步 I/O
同步 I/O 功能简单,使用也相对简单。异步 I/O 提供了复杂但非常强大的功能接口。
对所有I/O类型,包括:control、bulk、interrupt、isochronous,都统一使用 libusb_transfer 定义传输相关信息。
异步传输的过程为:
- 分配(allocate)一个 libusb_transfer 对象;
- 在 libusb_transfer 中填充相关信息;
- 提交 libusb_transfer 对象;
- 检查传输结果(同样保存在 libusb_transfer 中);
- 释放(Deallocation)相关资源;