一、libusb 简介
libusb 是一个用户空间访问 USB 设备的 C 库,特点:
- 使用 C 语言实现。
- 可移植性,目前支持的平台有 Linux,macOS,Windows,Android,OpenBSD/NetBSD,Haiku,Solaris。
- 支持全部的 USB 规范,从 1.0 到 3.1。
- 无特殊权限要求,比如在 Linux 平台访问串口设备的时候,需要 sudo 提升权限才能操作。
二、libusb 获取
注:GitHub 也有其仓库,但是缺乏生成 Makefile 的系列文件。所以最好还是通过官网下载压缩包。
三、libusb 涉及技术
针对 Linux 平台,涉及的技术有:
- sysfs:内核把一些 USB 设备的信息通过文件系统的方式呈现给了用户空间,应用通过读取相应文件即可获取所需信息。如遍历 /sys/bus/usb/devices/ 目录下的信息就可以获取各个设备的基本信息。
- libudev:用于 USB 设备的热插拔。
- Netlink:用于 USB 设备的热插拔。Netlink 是 Linux 提供的用于内核和用户空间之间的通信方式。一旦内核监测到系统设备有变化(如ADD/DEL/REMOVE),则通知用户进程。libudev 和 Netlink 二选一即可,可以认为 libudev 是对 Netlink 的封装。
- 多线程。
- 进程间通信:pipe/pipe2/eventfd。
- USB 规范:这部分可参见“果壳中的USB”系列文章。
四、libusb 目录简介
├── android:顾名思义,用于生成 Android 版本的 libusb 库及测试用例。
├── doc:用于生成 API 文档。在doc/目录下执行:doxygen doxygen.cfg 或者 make docs。
├── examples:libusb 的使用示例。后续代码分析即以各个示例作为实例。
├── libusb:libusb 核心代码
│ ├── os:平台相关的代码,支持
├── msvc:微软编译环境相关文件。
├── tests:libusb 的测试。
└── Xcode:Apple 平台相关文件。
examples示例简介
4.1 dpfp.c & dpfp_threaded.c
一款指纹识别器的应用程序,将采集到的指纹图像保存为文件。
用到了control、interrupt、bulk三种传输方式。
4.2 ezusb.c & fxload.c
“EZ-USB的固件下载程序,可实现下载固件(image)到Cypress EZ-USB microcontrollers,ezusb系列芯片使用端点0和厂商特定命令将数据写到片上SRAM,并且也支持写数据到CPUCS register或者eeprom。程序使用控制传输方式进行指令和数据的传输,libusb_control_transfer()的形参bmRequestType使用LIBUSB_REQUEST_TYPE_VENDOR(厂商自定义请求)。程序支持五种下载类型(Target type): an21, fx, fx2, fx2lp, fx3,支持四种固件(image)类型:“Intel HEX”, “Cypress 8051 IIC”, “Cypress 8051 BIX”, “Cypress IMG format”。”
4.4 hotplugtest.c
hotplugtest 用于监听系统中 USB 设备的 attached(插入)和 detached(拔出)。
实现原理及代码分析见:libusb(3)hotplugtest 实现分析
4.5 listdevs.c
获取并显示系统当前的 USB 设备信息,包含:VID、PID、bus 编号、设备地址、端口号。
实现原理及代码分析见:libusb(2)listdevs 实现分析
4.6 sam3u_benchmark.c
“Atmel SAM3U isochronous(等时传输)性能测试。程序不断接收来自SAM3U iso端点的数据,当按下CTRL-C时,计算花费时间和传输的总数据量。”
4.7 testlibusb.c
"打印usb设备列表的详细信息:包括设备描述符、配置、接口、端点描述符"
4.8 xusb.c
“一个综合的USB测试程序,包括:HID设备(xbox、PS3和Joystick)、Mass Storage,涉及control、interrupt、bulk传输。”
“其中Mass Storage可以使用普通的U盘进行测试,只需修改VID和PID即可,可以实现的功能有:读取描述符、查询U盘信息、读取U盘容量、读取U盘数据(因为没有使用文件系统,读取出来的数据是原始二进制数据)。”
“关于Mass Storage中涉及的SCSI命令,参考: USB Mass Stroage - SCSI指令格式详解。”
五、libusb 源码编译
5.1 系统信息
Ubuntu 14.04,Linux 4.4.0
5.2 编译器配置
Ubuntu 14.04 默认 gcc/g++ 版本为 4.8,需要升级编译器。方法如下:
$ sudo add-apt-repository ppa:ubuntu-toolchain-r/test $ sudo apt-get update $ sudo apt-get install gcc-5 g++-5
/usr/bin/gcc 和 /usr/bin/g++ 是软链接,修改使其指向我们新安装的编译器:
sudo ln -s /usr/bin/gcc-5 /usr/bin/gcc sudo ln -s /usr/bin/g++-5 /usr/bin/g++
5.3 Makefile
执行 ./configure 自动生成 Makefile。
按照上述步骤生成的 Makefile,在 make 的时候报错“aclocal-1.16 is missing on your system.”,很明显提示系统当前 aclocal 的版本不符合要求。
考虑到 libusb 源码没有多少文件,干脆自己写 Makefile,后续自己控制编译哪些文件。
源码分析所用的仓库:libusb_play.git