如果打开设备,QSerialPort 会导致程序停止(无限循环?)

dgr*_*rat 4 c++ qt qiodevice qtserialport qtcore

我想在串行设备上写入。不幸的是,我感觉 QSerialPort 在 linux 下没有正确实现。与其他方法 (python) 相比,我得到 !sometimes! 当我尝试调用时程序挂起:

serial.open(QIODevice::ReadWrite)
Run Code Online (Sandbox Code Playgroud)

我正在使用http://qt-project.org/wiki/QtSerialPort 中的示例(见下文)。QSerialPortInfo 工作正常,因此我可以在打开它之前搜索我的设备。该问题出现在所有 Qt 5.* 系列中。我目前正在使用 OpenSuse 存储库中的 5.3 测试版。其他工具或方法证明设备正在工作(Windows 或 Python)。

// Example use QSerialPortInfo
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
    qDebug() << "Name        : " << info.portName();
    qDebug() << "Description : " << info.description();
    qDebug() << "Manufacturer: " << info.manufacturer();

    // Example use QSerialPort
    QSerialPort serial;
    serial.setPort(info);
    if (serial.open(QIODevice::ReadWrite)) // Hang of the program
        serial.close();
}
Run Code Online (Sandbox Code Playgroud)

工作python脚本:

com_port = 4
baud_rate = '9600'
pySerial = serial.Serial(com_port, baud_rate)
Run Code Online (Sandbox Code Playgroud)

编辑:我用调试器测试过。至少在 linux 上似乎是 Qt 5 的问题。它看起来像与设备锁相连。

小智 5

我不知道帕普先生在抱怨什么;我能够在没有更多信息的情况下重现您的问题。

在 Linux 上,如果具有打开 QSerialPort 实例的 Qt 进程异常终止或 QSerialPort 实例在进程退出时没有被销毁,则锁定文件会挂起并可能导致问题。陈旧的锁定文件不应导致此问题;锁文件包含崩溃的应用程序的 PID,新的应用程序实例应该识别出不存在具有该 PID 的进程,并在创建新锁之前立即删除锁。strace 将随着退避时间的增加反复向您显示有问题的锁定文件,因为新进程会反复检查以查看过时的锁定文件是否已被删除或其他任何内容。因此,删除文件(例如,/var/lock/LCK..ttyS0);如果您运行崩溃的应用程序,您将拥有锁定文件。

随机附注:如果您通过 PyQt5 在 Python 中使用 QSerialPort(顺便说一下,它确实有效!),请确保在 Python 解释器退出之前明确删除了 QSerialPort 实例。如果您在 IPython 中操作端口,则在退出之前执行“%xdel portobject”。

这是一个愚蠢的解决方法,但如果您使用其他一些机制来确保您的程序没有两个实例正在运行并使用相同的端口 - 或者如果您根本不在乎 - 您可以删除一行代码在打开端口之前锁定文件。

恕我直言,Qt 不应该首先模仿完全毫无价值的 Windows 风格的保姆状态保护。我可以 sudo rm -rf / 它发生了!我什至可以 rm 串行端口。鉴于这种不受约束的、原始的、神一样的力量,我应该能够随时随地打开一个串口……