2017-07-05 102 views
1

我正在尝试使用libusb-1.0和QtUsb库进行USB设备访问。它是一个简单的批量设备,可以在我进行一些更新之前生效。 目前我使用libusb不能声明设备

Linux nadhh.fritz.box 4.11.8-200.fc25.x86_64 #1 SMP Thu Jun 29 16:13:56 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux 

,如果我作为用户或root运行,因为设备会由udev

[timestamp] [threadID] facility level [function call] <message> 
-------------------------------------------------------------------------------- 
[ 0.012281] [00000fc6] libusb: error [op_get_configuration] device unconfigured 
Type:1, cat:default, file:../src/qlibusb.cpp, line:114, f:virtual qint32 QUsbDevice::open(), msg:Cannot Claim Interface 
Type:1, cat:default, file:../src/qlibusb.cpp, line:168, f:void QUsbDevice::printUsbError(int), msg:libusb Error: Entity not found 
[ 0.951403] [00000fc6] libusb: warning [libusb_exit] application left some devices open 

这不要紧,如果被设置为集团用户和权限666没关系我运行作为用户或根,因为该装置会由udev 被设置为组用户和许可666任何提示欢迎

此致的Jürgen

将代码从

两者

QtUsb

一种Qt的跨平台的驱动程序库。 依赖于libusb-1.0。

特点

  • 批量传输
  • 设备插入/移除检测
  • 设备搜索

TODO

  • 中断传输
  • 同步传输

使用

文档还没有完成,你可以看看在此期间的例子。

文档

Doxygen文档可以在这里找到:http://fpoussin.github.io/doxygen/qtusb/

下载

Ubuntu的PPA:https://launchpad.net/~fpoussin/+archive/ubuntu/ppa 的Windows库即将推出。

#ifndef USBEXAMPLE_H 
    #define USBEXAMPLE_H 

    #include <QObject> 
    #include <QUsb> 

    const quint8 USB_PIPE_IN = 0x81; /* Bulk output endpoint for responses */ 
    const quint8 USB_PIPE_OUT = 0x01;  /* Bulk input endpoint for commands */ 
    const quint16 USB_TIMEOUT_MSEC = 300; 

    const quint16 vendor_id = 0x04e3; 
    const quint16 product_id= 0x0001; 

    class UsbExample : public QObject 
    { 
     Q_OBJECT 
    public: 
     explicit UsbExample(QObject *parent = 0); 
     ~UsbExample(void); 
     void setupDevice(void); 
     bool openDevice(void); 
     bool closeDevice(void); 
     void read(QByteArray *buf); 
     void write(QByteArray *buf); 

    signals: 

    public slots: 

    private: 
     QUsbManager mUsbManager; 
     QUsbDevice* mUsbDev; 

     QtUsb::DeviceFilter mFilter; 
     QtUsb::DeviceConfig mConfig; 
    }; 

    #endif // USBEXAMPLE_H 

CPP

#include <iostream> 
    #include "usbexample.h" 

    using namespace std; 

    #ifdef interface 
    #undef interface 
    #endif 

    UsbExample::UsbExample(QObject *parent) : QObject(parent) { 
     this->setupDevice(); 

     QByteArray send, recv; 

     send.append(".[]=R00[]=R01[]=R02$"); 

     if (this->openDevice()) { 
     cerr << "Device open!" << endl; 
     this->write(&send); 
     this->read(&recv); 
     } 
    } 

    UsbExample::~UsbExample() { delete mUsbDev; } 

    void UsbExample::setupDevice() { 
     /* There are 2 ways of identifying devices depending on the platform. 
     * You can use both methods, only one will be taken into account. 
     */ 

     mUsbDev = new QUsbDevice(); 
     mUsbDev->setDebug(true); 

    #if 1 
     // Bus 003 Device 004: ID 04e3:0001 Zilog, Inc. 
     mFilter.pid = 0x0001; 
     mFilter.vid = 0x04E3; 
    #else 
     mFilter.vid = 0x0c4b; 
     mFilter.pid = 0x0400; 
    #endif 

     // 
     mConfig.alternate = 0; 
     mConfig.config = 0; 
     mConfig.interface = 0; 
     mConfig.readEp = 0x81; 
     mConfig.writeEp = 0x02; 
    } 

    bool UsbExample::openDevice() { 
     cerr << "Opening" << endl; 

     QtUsb::DeviceStatus ds; 

     ds = mUsbManager.openDevice(mUsbDev, mFilter, mConfig); 

     if (ds == QtUsb::deviceOK) { 
     // Device is open 
     return true; 
     } 
     return false; 
    } 

    bool UsbExample::closeDevice() { 
     cerr << "Closing" << endl; 
     mUsbManager.closeDevice(mUsbDev); 
     return false; 
    } 

    void UsbExample::read(QByteArray *buf) { mUsbDev->read(buf, 1); } 

    void UsbExample::write(QByteArray *buf) { mUsbDev->write(buf, buf->size()); } 

    #include "usbexample.h" 
    #include <QCoreApplication> 
    #include <QTimer> 
    #include <iostream> 


    void customLogHandler(QtMsgType type, const QMessageLogContext& context, 
          const QString& msg) 
    { 
     // send the data to log file via the other thread 
     // emit writeToFile(type, context, msg); 

     // now output to debugger console 
    #ifdef Q_OS_WIN 
     OutputDebugString(text.toStdWString().c_str()); 
    #else 
     std::cerr << "Type:" << type << ", cat:" << context.category << ", file:" << context.file 
         << ", line:" << context.line 
         << ", f:" << context.function << ", msg:" << msg.toStdString() << std::endl; 
    #endif 
    } 


    int main(int argc, char *argv[]) { 
     qInstallMessageHandler(&customLogHandler); 
     QCoreApplication a(argc, argv); 
     QTimer timer; 

     QObject::connect(&timer, SIGNAL(timeout()), &a, SLOT(quit())); 

     timer.setInterval(1000); 
     timer.setSingleShot(true); 
     timer.start(); 

     UsbExample example; 

     return a.exec(); 
    } 
+0

你能分享你的代码吗?我可以看到错误消息“device unconfigured”。你需要调试。也许它更好,如果你启用libusb调试。 – Shaibal

+0

要启用更多的调试日志使用libusb_set_debug() – Shaibal

+0

我做到了,调试已启用。 –

回答

0

这是与配置有问题。在USB,你必须服从层次

设备描述符 - 配置描述符 - 接口描述 - 端点描述

http://www.beyondlogic.org/usbnutshell/usb1.shtml

如果在配置级别的错误的其他所有级别也未能

极有可能错误是在此代码:

mConfig.alternate = 0; 
    mConfig.config = 0; 
    mConfig.interface = 0; 
    mConfig.readEp = 0x81; 
    mConfig.writeEp = 0x02; 

问题是我不知道你的设备的USB树的结构,所以你必须这样做。您可以通过lsusb -vusb-devices获得结构和搜索装置的结构顺序“设备 - 配置 - 界面 - 端点

,如果你有需要修改上面的代码信息(即改变接口索引,替代设置,...)

的源代码的关键部分是

int conf; 
    libusb_get_configuration(mDevHandle, &conf); 

    if (conf != mConfig.config) { 
    if (mDebug) qDebug("Configuration needs to be changed"); 
    rc = libusb_set_configuration(mDevHandle, mConfig.config); 
    if (rc != 0) { 
     qWarning("Cannot Set Configuration"); 
     this->printUsbError(rc); 
     return -3; 
    } 
    } 
    rc = libusb_claim_interface(mDevHandle, mConfig.interface); 
    if (rc != 0) { 
    qWarning("Cannot Claim Interface"); 
    this->printUsbError(rc); 
    return -4; 
} 

源:https://github.com/fpoussin/QtUsb/blob/master/src/qlibusb.cpp

这是'Can not Claim Interface'错误消息来自的地方,因为设置准确的配置存在问题。作为说的尝试lsusb -vusb-devices得到正确的信息...