發(fā)現(xiàn)自己最近的記性越來越差了,估計(jì)是太頻繁的晚睡熬夜導(dǎo)致的吧...幾天前學(xué)的東西者吁,如果短時(shí)間不用窘俺,就會(huì)逐漸忘記,當(dāng)再次看到的時(shí)候复凳,會(huì)驚嘆“哇瘤泪,這么好的項(xiàng)目怎么才看到..不對,怎么感覺似曾相識”育八。对途。。
所以開始把學(xué)習(xí)的過程記錄下來髓棋,這樣印象能夠深刻些实檀。。
前陣子按声,稚暉君發(fā)布了ElectronBot--桌面機(jī)器人膳犹,通過usb協(xié)議與電腦端通訊,接收圖像和控制信息签则。小機(jī)器人本體的硬件+軟件已經(jīng)復(fù)刻完成了须床,現(xiàn)在需要開發(fā)電腦端的應(yīng)用。
稚暉君已經(jīng)提供了sdk和unity端的應(yīng)用實(shí)例渐裂,依托著示例正好可以學(xué)習(xí)下如何在電腦端開發(fā)usb軟件豺旬。
要在電腦端開發(fā)一個(gè)usb上位機(jī),考慮軟件能夠平臺通用(Linux+Window)那么一個(gè)能夠調(diào)動(dòng)電腦的usb外設(shè)的通用庫是必不可少的柒凉,而libusb就是一個(gè)很不錯(cuò)的選擇族阅。
libusb 是一個(gè)提供對 USB 設(shè)備的通用訪問的 C 庫。它幫助開發(fā)者能夠很快的實(shí)現(xiàn)應(yīng)用程序與USB設(shè)備的通信扛拨。
方便移植:使用單一的跨平臺 API耘分,它提供對 Linux、macOS、Windows 等 USB 設(shè)備的訪問求泰。
工作在用戶模式:應(yīng)用程序與設(shè)備通信不需要特殊權(quán)限或提升央渣。
版本無關(guān):支持所有版本的 USB 協(xié)議,從 1.0 到 3.1渴频。
在qt工程中配置libusb庫
首先下載libusb芽丹,我這里選的1.0.26版本的編譯后的lib,即libusb-1.0.26-binaries.7z卜朗,點(diǎn)擊鏈接直接下載
將下載好的壓縮包解壓到你的電腦上拔第,會(huì)看到如下的目錄結(jié)構(gòu),這些文件夾都是一樣的libusb庫场钉,只是通過不同的編譯器生成的蚊俺,可以從文件名看出,cygwin逛万、MinGW泳猬、MACos、VS2015宇植,每種又分別編譯了32位和64位版本得封,這里我qt里用的MinGW編譯器,所以就選擇了libusb-MinGW-x64版本指郁。
打開libusb-MinGW-x64文件夾忙上,可以看到三個(gè)文件夾,分別是bin闲坎、include和lib疫粥,其中bin中放著動(dòng)態(tài)鏈接庫,lib中放的是靜態(tài)鏈接庫腰懂,include中放的是頭文件手形。
將lib/libusb-1.0.a 、include\libusb-1.0\libusb.h拷貝到QT工程目錄中:(這里我就不介紹如何新建qt工程了)
然后打開qt工程悯恍,在qtcreate界面的工程名上右擊,點(diǎn)擊“添加庫”按鈕伙狐,這里我們選擇“外部庫”:
下一步后涮毫,我們在庫文件處點(diǎn)擊預(yù)覽,選中工程目錄下的libusb-1.0.a贷屎,平臺這里我把mac先去掉了(因?yàn)橐灿貌坏剑?/p>
鏈接這里可以選擇靜態(tài)的罢防,這樣就不需要調(diào)用動(dòng)態(tài)庫,但是編譯出的可執(zhí)行文件會(huì)適當(dāng)大些唉侄,選擇動(dòng)態(tài)咒吐,就需要將bin/msys-usb-1.0.dll拷貝到qt編譯輸出的目錄中,這里我用動(dòng)態(tài)的方式舉例
點(diǎn)擊下一步、完成后恬叹,打開工程的pro文件候生,我們可以看到庫相關(guān)配置已經(jīng)寫進(jìn)去了:
在qt的header目錄下將libusb.h加進(jìn)去:
至此,libusb庫就添加到qt的工程之中了绽昼,點(diǎn)下編譯唯鸭,理論上應(yīng)該不會(huì)報(bào)錯(cuò)。
小試牛刀硅确,跑個(gè)簡單的程序
在libusb的github倉庫里有個(gè)examples目溉,里面有不少的官方例程,這里我們參考最簡單的listdevs.c來試下libusb是否工作正常菱农。
在qt工程中缭付,我們新建一個(gè)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 <QtDebug>
#include "libusb.h"
class USB
{
public:
USB();
~USB();
void print_dev(void);
private:
libusb_device **devs;
};
#endif // USB_H
寫好后,在mainWindows.cpp只厘,我們創(chuàng)建USB實(shí)例
#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;
}
編譯運(yùn)行下烙丛,在debug窗口就可以看到說明libusb庫已經(jīng)能夠正常工作了。