4

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

serial.open(QIODevice::ReadWrite)

我正在使用来自http://qt-project.org/wiki/QtSerialPort的示例(见下文)。QSerialPortInfo 工作正常,因此我可以在打开设备之前搜索它。该问题出现在所有 Qt 5.* 系列中。我目前正在使用 OpenSuse 存储库中的 5.3 beta。其他工具或方法证明设备正在运行(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();
}

工作python脚本:

com_port = 4
baud_rate = '9600'
pySerial = serial.Serial(com_port, baud_rate)

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

4

2 回答 2

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 串行端口。有了这种无拘无束的、原始的、神一样的力量,我应该可以随时随地打开一个串口……

于 2014-05-23T23:16:08.227 回答
3

该类尝试获取串行端口的锁定。Line lockFileScopedPointer->lock();inbool QSerialPortPrivate::open(QIODevice::OpenMode mode) 可能应用程序以 root 身份运行,当应用程序以不同用户身份运行时,锁定文件不可访问。运行 strace 进行检查。

于 2014-05-14T01:59:09.567 回答