使用 Linux 伪终端测试 QSerialPort

Posted

技术标签:

【中文标题】使用 Linux 伪终端测试 QSerialPort【英文标题】:Using Linux pseudoterminal to test QSerialPort 【发布时间】:2018-03-28 21:16:26 【问题描述】:

我想通过伪终端测试使用 Qt 串行端口的应用程序。根据我实现的手册页:

// open master
QSerialPort master("/dev/ptmx");
master.open(QSerialPort::ReadWrite);
int master_fd = master.handle();

// get device name of slave pseudoterminal
constexpr size_t PTSNAME_BUFFER_LENGTH = 128;
char ptsname_buffer[PTSNAME_BUFFER_LENGTH];
if (ptsname_r(master_fd, ptsname_buffer, PTSNAME_BUFFER_LENGTH) != 0)
    return 0;

// grant access to the slave
if (grantpt(master_fd) != 0)
    return 0;

// unlock the slave
if (unlockpt(master_fd) != 0)
    return 0;

// open slave
std::cout << "Slave pseudoterminal: " << ptsname_buffer << std::endl;
QSerialPort slave(ptsname_buffer);
slave.open(QSerialPort::ReadWrite);

// test communication
master.write("Hello World");
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::cout << "Received: " << slave.readAll().toStdString() << std::endl;

创建从属设备似乎可行(在我的例子中,它是在/dev/pts/2 创建的)。但是,slave.readAll() 命令总是返回一个空字符串。

是否可以使用伪终端测试 QSerialPort?

【问题讨论】:

还是用 tty0tty 比较好。而且,是的,您需要在 qt-event 循环中,或者,至少要使用 waitForXX() 方法。 【参考方案1】:

Qt 在事件循环中执行,因此您需要等待通信被处理,在 Qt 中您应该使用信号异步工作:

ma​​in.cpp

#include <QCoreApplication>
#include <QSerialPort>

#include <iostream>

int main(int argc, char *argv[])

    QCoreApplication a(argc, argv);

    QSerialPort master("/dev/ptmx");
    if(!master.open(QSerialPort::ReadWrite))
        std::cout<<"The master port was not opened";

    int master_fd = master.handle();

    // get device name of slave pseudoterminal
    constexpr size_t PTSNAME_BUFFER_LENGTH = 128;
    char ptsname_buffer[PTSNAME_BUFFER_LENGTH];
    if (ptsname_r(master_fd, ptsname_buffer, PTSNAME_BUFFER_LENGTH) != 0)
        return -1;

    // grant access to the slave
    if (grantpt(master_fd) != 0)
        return -1;

    // unlock the slave
    if (unlockpt(master_fd) != 0)
        return -1;

    // open slave
    std::cout << "Slave pseudoterminal: " << ptsname_buffer << std::endl;
    QSerialPort slave(ptsname_buffer);
    if(!slave.open(QSerialPort::ReadWrite))
        std::cout<<"The slave port was not opened";

    QObject::connect(&slave, &QSerialPort::readyRead, [&]()
        std::cout << "Received: " << slave.readAll().toStdString() << std::endl;
        a.quit();
    );
    // test communication
    master.write("Hello World");
    return a.exec();

输出:

Slave pseudoterminal: /dev/pts/3
Received: Hello World

注意:不要使用std::this_thread::sleep_for,因为它是阻止事件循环执行的阻塞任务。

【讨论】:

以上是关于使用 Linux 伪终端测试 QSerialPort的主要内容,如果未能解决你的问题,请参考以下文章

Linux终端概念,伪终端,串行终端,虚拟终端,控制台

【Linux操作】---终端神器tmux

学习linux-基础二(终端类型)

实验楼 linux 学习

终端,虚拟终端,伪终端

linux tty伪tty是什么?