【问题标题】:In QT how can I detect when a USB port switches from serial mode to DFU when connected to an STM32在 QT 中,当连接到 STM32 时,如何检测 USB 端口何时从串行模式切换到 DFU
【发布时间】:2019-12-24 06:28:23
【问题描述】:

我有一个 Qt5.12.4 MinGw64 应用程序,我想在其中捕获 USB 事件。在 Windows 10 中,STM/USB 的 MS 驱动程序会发出错误消息,我可以将其用作触发器。不优雅但它有效,直到我尝试在 Win7-8.1 应用程序中运行它,其中驱动程序是具有 VCP 包装器的第三方 STM 驱动程序。我想我需要采用 libusb 来尝试捕捉端口状态的变化,但我不知道如何进行。我可以在设备管理器中看到端口信息,我只是不知道如何访问它。一些问题在我脑海中萦绕……

1) 我可以只调用操作系统来读取端口信息吗? (如果有,怎么做?)

2) libusb 和 QSerialport 可以在同一个端口上共存吗?

3) 我应该对 LibUSB1.0 进行哪些调用来查询端口状态?

4) 是否有像 lsusb (wmic??) 这样的 Windows cli 实用程序可以在其中抓取数据?

5) 哪种解决方案可能是最好的跨平台解决方案?

我正在使用这个触发器来启动 dfuse 作为一个在我的 STM 板上自动更新固件的进程。

我查看了 libusb1.0 文档,但我不明白如何使用它。如果这是正确的解决方案,将非常感谢您提供如何查询 Com 端口数据和状态的示例。

我尝试在串行或 DFU 状态下使用 qDebug() 打印出所有 serialportInfo 数据,但没有任何有用的东西可以用作触发器。

USB 串口模式 = 串口信息为:("COM3", "USB Serial Device", "Microsoft", "00000000001A", "\\.\COM3", "483", "5740", "1" , "没有数据", "1")

USB DFU 模式 = 串口信息为:("COM3", "N/A", "N/A", "N/A", "\\.\COM3", "N/A", " N/A”、“无数据”、“无数据”、“无数据”)

我需要一些关于如何获取此端口信息的指导,因此我没有任何重要的代码,但我包含了我的工作流程函数的摘录。

此代码可以很好地实际执行固件加载。我只需要一种从 USB 端口状态更改中实际触发它的方法

void updateDevice_Dialog::update_firmware(QString fileName)
{
    qDebug() << "Updating firmware: " << fileName ;

    QDir dir;

    ui->progress_label->setText("Preparing to update Firmware .....");
    if(dir.setCurrent(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)+"/firmware"))
    {
        QSettings settings;
        QString comPort = settings.value("USBPort").toString();
        ui->progress_label->setText("Setting port to: "+comPort+" and starting download .....");
        ui->avr_progressBar->setValue(0);
        ui->avr_progressBar->setRange(0,100);
        ui->avr_progressBar->setHidden(false);

        progress_steps = 0;  //reset avrProcess line output counter;
        qDebug() << "Starting process for stm-dfu on serial port: " << comPort;

        connect(avr_Process,SIGNAL(error(QProcess::ProcessError)),this,SLOT(process_error(QProcess::ProcessError)));
        connect(avr_Process,SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(process_finished(int,QProcess::ExitStatus)));
        connect(avr_Process,SIGNAL(readyReadStandardOutput()),this,SLOT(process_readLine()));
        connect(avr_Process,SIGNAL(errorOccurred(QProcess::ProcessError)),avr_Process,SLOT(kill()));
        connect(avr_Process,SIGNAL(error(QProcess::ProcessError)),ui->avr_progressBar,SLOT(close()));

        QString dfu_command = "\""+QCoreApplication::applicationDirPath()+"/Tools/\"dfusecommand -c -d --v --fn "
                              "\""+QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)+"/firmware/\""+fileName;

        qDebug().noquote() << "dfu command string is: "<< dfu_command << "  Current dir is: " << dir.currentPath();


        avr_Process->start(dfu_command);
        avr_Process->waitForFinished(20000);
}
}

【问题讨论】:

    标签: stm32 libusb-1.0 qtserialport dfu


    【解决方案1】:

    从主机系统的角度来看,将微控制器重新启动到 DFU 看起来就像原始设备断开连接,不久之后又插入了一个完全不同的设备。

    如果您需要注意这一点,请设置a libusb hotplug callback,以便在连接 DFU 设备时收到通知。

    【讨论】:

    • 这就是我为 Windows 10 所做的事情,因为新的 Windows 驱动程序确实遇到了断开连接,但使用 VCP 驱动程序似乎看不到“热插拔”事件。我将尝试看看我是否可以在不与 QSerialport 冲突的情况下使用此功能,只是为了看看我能从中得到什么并回复你。感谢您的洞察力
    • 使用您的链接我将它添加到我的项目中并链接了 libusb 库,但现在我需要调用它并且我不知道我需要在调用中包含的值。我有使用 Qt 的经验,它让我在很短的时间内做了很多事情,但是 C 和 C++ 的一些底层机制仍然超出我的能力范围。根据文档,我的函数调用需要这些输入
    • int libusb_hotplug_register_callback \n int hotplug_callback(struct libusb_context *ctx, struct libusb_device *dev, libusb_hotplug_event event, void *user_data)。

      我知道我可以将 LIBUSB_HOTPLUG_MATCH_ANY 用于其中一些变量,但我不知道如何在 Qt 中设置回调,其他一些也超出了我的范围。我只想要一个 QString 的快速 QList,它说明驱动程序处于什么模式,这将返回一个“int.
    猜你喜欢
    • 2021-06-06
    • 1970-01-01
    • 1970-01-01
    • 2014-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-28
    • 1970-01-01
    相关资源
    最近更新 更多