简体   繁体   English

在QT中,如何在连接到STM32时检测USB端口何时从串行模式切换到DFU

[英]In QT how can I detect when a USB port switches from serial mode to DFU when connected to an STM32

I have a Qt5.12.4 MinGw64 app where I want to catch a USB event. 我有一个Qt5.12.4 MinGw64应用程序,我想在其中捕获USB事件。 In Windows 10 the MS driver for STM/USB emits error messages and I can use that as a trigger. 在Windows 10中,用于STM / USB的MS驱动程序发出错误消息,我可以将其用作触发器。 Inelegant but it works, until I try to run it in a Win7-8.1 app where the driver is a third party STM driver with a VCP wrapper. 效果不佳,但是可以正常工作,直到我尝试在Win7-8.1应用程序中运行它,该驱动程序是带有VCP包装程序的第三方STM驱动程序。 I am thinking I need to adopt libusb to try and catch the ports change of state, but I am at a loss as how to proceed. 我认为我需要采用libusb来尝试捕获端口状态的变化,但是我对如何进行操作感到茫然。 I can see the port info in Device Manager, I just dont know how to get to it. 我可以在“设备管理器”中看到端口信息,但我只是不知道该怎么去。 Some of the questions going through my head.... 我脑海中有些疑问...

1) Can I just make an OS call to read the port info? 1)我可以打一个OS来读取端口信息吗? (if so, how?) (如果是,如何?)

2) Can libusb and QSerialport co-exist on the same port? 2)libusb和QSerialport可以在同一端口上共存吗?

3) What calls to LibUSB1.0 do I make to query the port status? 3)我如何调用LibUSB1.0来查询端口状态?

4) Is there a Windows cli utility like lsusb (wmic??) where I could scrape the data? 4)是否有Windows cli实用程序,如lsusb(wmic ??),可以在其中刮擦数据?

5) Which solution is likely to be the best cross platform solution? 5)哪种解决方案可能是最佳的跨平台解决方案?

I am using this trigger to start dfuse as a process that does a firmware update automatically on my STM board. 我正在使用此触发器来启动dfuse,因为它可以在STM板上自动进行固件更新。

I have looked over the libusb1.0 docs but I do not understand just how I can use it. 我查看了libusb1.0文档,但我不知道如何使用它。 If that is correct solution, an example of how to query the Com port data and state would be most appreciated. 如果那是正确的解决方案,那么将非常感谢有关如何查询Com端口数据和状态的示例。

I tried using qDebug() to print out all of the serialportInfo data, while in serial or DFU state, but there is nothing there that is useful that I can use as a trigger. 我尝试使用qDebug()在串行或DFU状态下打印出所有serialportInfo数据,但是没有什么可以用作触发器的有用信息了。

USB serial mode = Serial port info is: ("COM3", "USB Serial Device", "Microsoft", "00000000001A", "\\\\.\\COM3", "483", "5740", "1", " no data", "1") USB串行模式=串行端口信息为:(“ COM3”,“ USB串行设备”,“ Microsoft”,“ 00000000001A”,“ \\\\。\\ COM3”,“ 483”,“ 5740”,“ 1”,“数据”,“ 1”)

USB DFU mode = Serial port info is: ("COM3", "N/A", "N/A", "N/A", "\\\\.\\COM3", "N/A", "N/A", "no data", " no data", "no data") USB DFU模式=串行端口信息为:(“ COM3”,“ N / A”,“ N / A”,“ N / A”,“ \\\\。\\ COM3”,“ N / A”,“ N / A “,“无数据”,“无数据”,“无数据”)

I need some direction as to how to grab this port info so I dont really have any code that matters, but I am including an excerpt of my working process function. 关于如何获取此端口信息,我需要一些指导,因此我实际上没有任何重要的代码,但是我包括了我的工作流程功能的摘录。

This code works just fine to actually perform the firmware load. 该代码可以很好地执行固件加载。 I just need a way to actually trigger it from a USB port change of state 我只需要一种从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);
}
}

From the perspective of the host system, rebooting the microcontroller into DFU will look like the original device was disconnected, and a completely different device was plugged in shortly afterwards. 从主机系统的角度来看,将微控制器重新启动至DFU看起来就像是断开了原始设备的连接,之后不久又插入了完全不同的设备。

If you need to watch for this, set up a libusb hotplug callback so that you'll be notified when the DFU device is attached. 如果需要注意这一点,请设置libusb热插拔回调,以便在连接DFU设备时收到通知。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM