Using Linux pseudoterminal to test QSerialPort

戏子无情 提交于 2020-01-02 16:23:12

问题


I would like to test an application using Qt serial ports with a pseudoterminal. According to the man pages I implemented:

// 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;

Creating the slave device seems to work (in my case it is created at /dev/pts/2). However, the slave.readAll() command always returns an empty string.

Is it possible to test the QSerialPort with a pseudoterminal?


回答1:


Qt is executed inside an event loop so you need to wait for the communication to be processed, in Qt you should work asynchronously using the signals:

main.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();
}

Output:

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

Note: Do not use std::this_thread::sleep_for since it is a blocking task that prevents the event loop from executing.



来源:https://stackoverflow.com/questions/49544318/using-linux-pseudoterminal-to-test-qserialport

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!