发现自己最近的记性越来越差了,估计是太频繁的晚睡熬夜导致的吧...几天前学的东西,如果短时间不用,就会逐渐忘记,当再次看到的时候,会惊叹“哇,这么好的项目怎么才看到..不对,怎么感觉似曾相识”。。。
所以开始把学习的过程记录下来,这样印象能够深刻些。。
前阵子,稚晖君发布了ElectronBot--桌面机器人,通过usb协议与电脑端通讯,接收图像和控制信息。小机器人本体的硬件+软件已经复刻完成了,现在需要开发电脑端的应用。
稚晖君已经提供了sdk和unity端的应用实例,依托着示例正好可以学习下如何在电脑端开发usb软件。
要在电脑端开发一个usb上位机,考虑软件能够平台通用(Linux+Window)那么一个能够调动电脑的usb外设的通用库是必不可少的,而libusb就是一个很不错的选择。
libusb 是一个提供对 USB 设备的通用访问的 C 库。它帮助开发者能够很快的实现应用程序与USB设备的通信。
方便移植:使用单一的跨平台 API,它提供对 Linux、macOS、Windows 等 USB 设备的访问。
工作在用户模式:应用程序与设备通信不需要特殊权限或提升。
版本无关:支持所有版本的 USB 协议,从 1.0 到 3.1。
在qt工程中配置libusb库
首先下载libusb,我这里选的1.0.26版本的编译后的lib,即libusb-1.0.26-binaries.7z,点击链接直接下载
将下载好的压缩包解压到你的电脑上,会看到如下的目录结构,这些文件夹都是一样的libusb库,只是通过不同的编译器生成的,可以从文件名看出,cygwin、MinGW、MACos、VS2015,每种又分别编译了32位和64位版本,这里我qt里用的MinGW编译器,所以就选择了libusb-MinGW-x64版本。
打开libusb-MinGW-x64文件夹,可以看到三个文件夹,分别是bin、include和lib,其中bin中放着动态链接库,lib中放的是静态链接库,include中放的是头文件。
将lib/libusb-1.0.a 、include\libusb-1.0\libusb.h拷贝到QT工程目录中:(这里我就不介绍如何新建qt工程了)
然后打开qt工程,在qtcreate界面的工程名上右击,点击“添加库”按钮,这里我们选择“外部库”:
下一步后,我们在库文件处点击预览,选中工程目录下的libusb-1.0.a,平台这里我把mac先去掉了(因为也用不到)
链接这里可以选择静态的,这样就不需要调用动态库,但是编译出的可执行文件会适当大些,选择动态,就需要将bin/msys-usb-1.0.dll拷贝到qt编译输出的目录中,这里我用动态的方式举例
点击下一步、完成后,打开工程的pro文件,我们可以看到库相关配置已经写进去了:
在qt的header目录下将libusb.h加进去:
至此,libusb库就添加到qt的工程之中了,点下编译,理论上应该不会报错。
小试牛刀,跑个简单的程序
在libusb的github仓库里有个examples,里面有不少的官方例程,这里我们参考最简单的listdevs.c来试下libusb是否工作正常。
在qt工程中,我们新建一个c++ 类,命名为USB
建好后,按照listdevs.c,我们写下如下代码
// USB.cpp
#include "USB.h"
USB::USB()
{
int r;
size_t cnt;
r = libusb_init(NULL);
if(r < 0)
qDebug() << r << endl;
cnt = libusb_get_device_list(NULL,&devs);
if(cnt < 0)
libusb_exit(NULL);
qDebug() << cnt << endl;
}
USB::~USB()
{
libusb_free_device_list(devs,1);
libusb_exit(NULL);
}
void USB::print_dev(void)
{
libusb_device *dev;
int i = 0;
int j = 0;
uint8_t path[8];
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.";
break;
}
qDebug("%04x:%04x (bus %d, device %d)",desc.idVendor,desc.idProduct,
libusb_get_bus_number(dev),libusb_get_device_address(dev));
r = libusb_get_port_numbers(dev,path,sizeof(path));
if(r > 0)
{
qDebug("path : %d",path[0]);
for(j = 1;j < r;j++)
qDebug(".%d",path[j]);
}
}
}
USB.h文件
#ifndef USB_H
#define USB_H
#include
#include "libusb.h"
class USB
{
public:
USB();
~USB();
void print_dev(void);
private:
libusb_device **devs;
};
#endif // USB_H
写好后,在mainWindows.cpp,我们创建USB实例
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
usb = new USB;
usb->print_dev();
}
MainWindow::~MainWindow()
{
delete ui;
}
编译运行下,在debug窗口就可以看到
说明libusb库已经能够正常工作了。