libusb 无法声明设备

J.W*_*ers 5 linux usb libusb

我正在尝试使用 libusb-1.0 和 QtUsb 库进行 USB 设备访问。它是一个简单的批量设备,在我进行一些更新之前就可以工作。\n目前我使用

\n\n
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\n
Run Code Online (Sandbox Code Playgroud)\n\n

我以用户或 root 身份运行并不重要,因为设备将被 udev 设置为组用户和权限 666

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

我是否以用户或 root 身份运行并不重要,因为设备将被 udev 设置为组用户和权限 666\n欢迎任何提示

\n\n

此致 J\xc3\xbcrgen

\n\n

代码

\n\n

取自

\n\n

QtUsb

\n\n

\n

\n\n

用于 Qt 的跨平台 USB 库。\n依赖于 libusb-1.0。

\n\n

特征

\n\n
    \n
  • 批量转账
  • \n
  • 设备插入/移除检测
  • \n
  • 设备搜索
  • \n
\n\n

去做

\n\n
    \n
  • 中断传输
  • \n
  • 同步传输
  • \n
\n\n

用法

\n\n

文档尚未完成,您可以同时查看示例。

\n\n

文档

\n\n

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

\n\n

下载

\n\n

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

\n\n

标头

\n\n
    #ifndef USBEXAMPLE_H\n    #define USBEXAMPLE_H\n\n    #include <QObject>\n    #include <QUsb>\n\n    const quint8 USB_PIPE_IN = 0x81;   /* Bulk output endpoint for responses */\n    const quint8 USB_PIPE_OUT = 0x01;      /* Bulk input endpoint for commands */\n    const quint16 USB_TIMEOUT_MSEC = 300;\n\n    const quint16 vendor_id = 0x04e3;\n    const quint16 product_id= 0x0001;\n\n    class UsbExample : public QObject\n    {\n        Q_OBJECT\n    public:\n        explicit UsbExample(QObject *parent = 0);\n        ~UsbExample(void);\n        void setupDevice(void);\n        bool openDevice(void);\n        bool closeDevice(void);\n        void read(QByteArray *buf);\n        void write(QByteArray *buf);\n\n    signals:\n\n    public slots:\n\n    private:\n        QUsbManager mUsbManager;\n        QUsbDevice* mUsbDev;\n\n        QtUsb::DeviceFilter mFilter;\n        QtUsb::DeviceConfig mConfig;\n    };\n\n    #endif // USBEXAMPLE_H\n
Run Code Online (Sandbox Code Playgroud)\n\n

程序文件

\n\n
    #include <iostream>\n    #include "usbexample.h"\n\n    using namespace std;\n\n    #ifdef interface\n    #undef interface\n    #endif\n\n    UsbExample::UsbExample(QObject *parent) : QObject(parent) {\n      this->setupDevice();\n\n      QByteArray send, recv;\n\n      send.append(".[]=R00[]=R01[]=R02$");\n\n      if (this->openDevice()) {\n        cerr << "Device open!" << endl;\n        this->write(&send);\n        this->read(&recv);\n      }\n    }\n\n    UsbExample::~UsbExample() { delete mUsbDev; }\n\n    void UsbExample::setupDevice() {\n      /* There are 2 ways of identifying devices depending on the platform.\n       * You can use both methods, only one will be taken into account.\n       */\n\n      mUsbDev = new QUsbDevice();\n      mUsbDev->setDebug(true);\n\n    #if 1\n      // Bus 003 Device 004: ID 04e3:0001 Zilog, Inc.\n      mFilter.pid = 0x0001;\n      mFilter.vid = 0x04E3;\n    #else\n      mFilter.vid = 0x0c4b;\n      mFilter.pid = 0x0400;\n    #endif\n\n      //\n      mConfig.alternate = 0;\n      mConfig.config = 0;\n      mConfig.interface = 0;\n      mConfig.readEp = 0x81;\n      mConfig.writeEp = 0x02;\n    }\n\n    bool UsbExample::openDevice() {\n      cerr << "Opening" << endl;\n\n      QtUsb::DeviceStatus ds;\n\n      ds = mUsbManager.openDevice(mUsbDev, mFilter, mConfig);\n\n      if (ds == QtUsb::deviceOK) {\n        // Device is open\n        return true;\n      }\n      return false;\n    }\n\n    bool UsbExample::closeDevice() {\n      cerr << "Closing" << endl;\n      mUsbManager.closeDevice(mUsbDev);\n      return false;\n    }\n\n    void UsbExample::read(QByteArray *buf) { mUsbDev->read(buf, 1); }\n\n    void UsbExample::write(QByteArray *buf) { mUsbDev->write(buf, buf->size()); }\n\n    #include "usbexample.h"\n    #include <QCoreApplication>\n    #include <QTimer>\n    #include <iostream>\n\n\n    void customLogHandler(QtMsgType type, const QMessageLogContext& context,\n                          const QString& msg)\n    {\n       // send the data to log file via the other thread\n       // emit writeToFile(type, context, msg);\n\n       // now output to debugger console\n    #ifdef Q_OS_WIN\n        OutputDebugString(text.toStdWString().c_str());\n    #else\n        std::cerr << "Type:" << type << ", cat:" << context.category << ", file:" << context.file\n                      << ", line:" << context.line\n                      << ", f:" << context.function << ", msg:" << msg.toStdString() << std::endl;\n    #endif\n    }\n\n\n    int main(int argc, char *argv[]) {\n        qInstallMessageHandler(&customLogHandler);\n      QCoreApplication a(argc, argv);\n      QTimer timer;\n\n      QObject::connect(&timer, SIGNAL(timeout()), &a, SLOT(quit()));\n\n      timer.setInterval(1000);\n      timer.setSingleShot(true);\n      timer.start();\n\n      UsbExample example;\n\n      return a.exec();\n    }\n
Run Code Online (Sandbox Code Playgroud)\n

ral*_*htp 2

这是配置问题。在USB中你必须遵守层次结构

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

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

如果配置级别出现错误,所有其他级别也会失败

错误很可能出现在这段代码中:

  mConfig.alternate = 0;
  mConfig.config = 0;
  mConfig.interface = 0;
  mConfig.readEp = 0x81;
  mConfig.writeEp = 0x02;
Run Code Online (Sandbox Code Playgroud)

问题是我不知道您设备的 USB 树的结构,所以您必须这样做。lsusb -v您可以通过或获取结构usb-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;
}
Run Code Online (Sandbox Code Playgroud)

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

这就是“无法声明接口”错误消息的来源,因为设置准确的配置存在问题。正如所说,尝试lsusb -vusb-devices获取正确的信息......