libusb 设计了一系列的外部API 为应用程序所调用,通过这些API应用程序可以操作硬件,从libusb的源代码可以看出,这些API 调用了内核的底层接口,和kernel driver中所用到的函数所实现的功能差不多,只是libusb更加接近USB 规范。使得libusb的使用也比开发内核驱动相对容易的多。(From: 百度百科 ) 0x00 下载 libusb 在 libusb 项目主页( http://libusb.info )我们可以找到最新的源码,下载下来,并且解压。这里我下载的是 libusb-1.0.20.tar.bz2 ,把它解压出来。 0x01 安装 libusb
cd libusb-1.0.20/
./configure
make install
这时就已经在机器上编译安装完成了 libusb 0x02 运行示例程序
cd examples/
	然后我们看到在 examples/ 目录下多了几个可执行程序:
Usage: fxload [-v] [-V] [-t type] [-d vid:pid] [-p bus,addr] [-s loader] -i firmware
  -i <path>       -- Firmware to upload
  -s <path>       -- Second stage loader
  -t <type>       -- Target type: an21, fx, fx2, fx2lp, fx3
  -d <vid:pid>    -- Target device, as an USB VID:PID
  -p <bus,addr>   -- Target device, as a libusb bus number and device address path
  -v              -- Increase verbosity
  -q              -- Decrease verbosity (silent mode)
  -V              -- Print program version
xusb:USB 测试程序
usage: /Users/jason/Downloads/libusb-1.0.20/examples/.libs/xusb [-h] [-d] [-i] [-k] [-b file] [-l lang] [-j] [-x] [-s] [-p] [-w] [vid:pid]
   -h      : display usage
   -d      : enable debug output
   -i      : print topology and speed info
   -j      : test composite FTDI based JTAG device
   -k      : test Mass Storage device
   -b file : dump Mass Storage data to file 'file'
   -p      : test Sony PS3 SixAxis controller
   -s      : test Microsoft Sidewinder Precision Pro (HID)
   -x      : test Microsoft XBox Controller Type S
   -l lang : language to report errors in (ISO 639-1)
   -w      : force the use of device requests when querying WCID descriptors
If only the vid:pid is provided, xusb attempts to run the most appropriate test
我们以 listdevs 为例,执行测试程序:
./listdevs
执行结果:
05ac:8406 (bus 20, device 3) path: 7
05ac:828f (bus 20, device 20) path: 3.3
0a5c:4500 (bus 20, device 27) path: 3
05ac:8005 (bus 20, device 0)
在Windows平台、MAC 平台和Linux平台下都大量存在着库。本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。
由于Windows、MAC和Linux的平台不同(主要是编译器、汇编器和连接器的不同),因此二者库的二进制是不兼容的。 Linux下的库有两种:静态库共享库(动态库)。二者的不同点在于代码被载入的时刻不同。 静态库的代码在编译过程中已经被载入可执行程序,因此体积较大。 共享库的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此代码体积较小。 创建静态链接库 0x00 写一个静态链接库 hello.h
gcc -c hello.c
gcc 中 -c 的编译选项的意思是使用GNU汇编器将源文件转化为目标代码之后就结束,在这种情况下,只调用了C编译器(ccl)和汇编器(as),而连接器(ld)并没有被执行,所以输出的目标文件不会包含作为程序在被装载和执行时所必须的包含信息,但它可以在以后被连接到一个程序。 我们执行 ls 命令会看到目录下多了一个 hello.o 文件,它就是 hello.c 编译的目标代码 0x02 创建静态链接库 注意,gcc会在静态库名前加上前缀lib,然后追加扩展名.a得到的静态库文件名来查找静态库文件,因此,我们在写需要连接的库时,只写名字就可以,如libhello.a的库,只写: -lhello
gcc -o main main.c -L. -lhello
gcc -dynamiclib -o hello.dylib hello.o
我们使用 ls 命令可以看到目录下多了 hello.dylib,它就是创建的动态链接库(.dylib是 MAC 系统下的,Windows 下是.dll, Linux 下是.so) 0x00 链接动态链接库
gcc -o main1 main.c -L. -lhello
将 libusb 对应的库文件复制到该目录下,因为我所使用的平台是 MAC OS X,所对应的库文件应当是以 .dylib为扩展名的,我们在 libusb 源码文件夹下的 /libusb/.libs/ 目录下找到 libusb-1.0.0.dylib 然后复制到刚刚创建的目录下 并且将 libusb 的头文件 libusb.h 加入到项目中 0x01 修改 QT 项目编译选项 修改 QT 项目中的 .pro 文件,加入下面几行: int initUsbDevices(); QString getVidPid(libusb_device **devs); void showAllUsbDevices(QList<STUUSBDevices> lst); void setRunStatus(); void run(); bool isStop; #endif // GETUSBINFO
getusbinfo.cpp QList<STUUSBDevices> lstUsb; while ((dev = devs[i++]) != NULL) { struct libusb_device_descriptor desc; int r = libusb_get_device_descriptor(dev, &desc); if (r < 0) { qDebug()<<"failed to get device descriptor"<<stderr; return ""; printf("%04x:%04x (bus %d, device %d)\n", desc.idVendor, desc.idProduct, libusb_get_bus_number(dev), libusb_get_device_address(dev)); STUUSBDevices stu; stu.idProduct = QString::number(desc.idProduct); stu.idVendor = QString::number(desc.idVendor); stu.iManufacturer = QString::number(desc.iManufacturer); stu.iSerialNumber = QString::number(desc.iSerialNumber); lstUsb.append(stu); showAllUsbDevices(lstUsb); return QString(lstUsb[0].idProduct); void GetUsbInfo::showAllUsbDevices(QList<STUUSBDevices> lst) for(int i=0;i<lst.count();i++) qDebug()<<"vid: "<<lst.at(i).idVendor<<"\n" <<"pid:"<<lst.at(i).idProduct<<"\n" <<"serNumber:"<<lst.at(i).iSerialNumber<<"\n" <<"Manufacturer:"<<lst.at(i).iManufacturer<<"\n"; void GetUsbInfo::setRunStatus() isStop = true; void GetUsbInfo::run() qDebug()<<"GetUsbInfo::run() "<<endl; while (!isStop) initUsbDevices(); sleep(10); main.cpp ```bash Starting /Users/jason/Project/QTDemos/build-Testlibusb-Desktop_Qt_5_5_1_clang_64bit-Debug/Testlibusb.app/Contents/MacOS/Testlibusb... vid: "1452" pid: "33798" serNumber: "5" Manufacturer: "3" vid: "1452" pid: "33423" serNumber: "0" Manufacturer: "1" vid: "2652" pid: "17664" serNumber: "0" Manufacturer: "1" vid: "1452" pid: "32773" serNumber: "0" Manufacturer: "0" 最终我们获得了当前 MAC 上的 USB 设备列表