[SOLVED]QSerialPort: Strange difference from Win to Linux



  • I arrange a QWidget with some buttons that send commands to an instrument for measurement: according to the sent command, the instruments will answer.
    I use a connector from ReadyRead signal:

    connect(serial, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
    I note some difference in Windows with respect to Linux: in Win all works perfectly (command sent and correct answer return). In Linux command sent is OK, but it seems connector doesn't work (placing a breakpoint at the beginning of my slot "onReadyRead", program never enters here).

    Any idea?



  • alsa - could you provide system/Qt versions?

    Unfortunately I do not have solution for you but I just wanted to report exactly the same, so I'll make use of your post to "complain" :) - most probably the reason for our problems is the same.

    I used QSerialPort already for some time and it worked perfectly on Linux (I'm using Ubuntu 14.04.3 64bits). It had some problems on Windows (which I reported previously on this Forum) but they were quickly fixed and since then everything was smooth.

    However recently I upgraded from 5.4 (or maybe 5.4.1) to 5.4.2 and
    With the latest upgrade I've noticed that there is problem with QSerialPort not reading from virtual port on Linux . I've tried reinstalling Qt and now I have 5.5.0 but the behaviour is the same. My program is to big to post it here (as alsa I'm using async reading and my readyRead() callback never enters) but below is simple sample program that displays the same problem together with some info about expected/obtained results.

    So this sample is just a simple writing/reading in a loop (I've tried to postpone opening till after event loop starts in case it helps - but it doesn't):

    #include <QCoreApplication>
    #include <QSerialPort>
    #include <QDebug>
    
    QSerialPort port;
    QTimer tmr;
    
    void port_open(QString name)
    {
        port.setPortName(name);
        if (! port.open(QIODevice::ReadWrite)) {
            qDebug() << "Failure to open port:" << port.errorString();
            return;
        }
        port.setBaudRate(QSerialPort::Baud115200);
        port.setDataBits(QSerialPort::Data8);
        port.setParity(QSerialPort::NoParity);
        port.setStopBits(QSerialPort::OneStop);
        port.setFlowControl(QSerialPort::NoFlowControl);
    
        port.clear();
    }
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        QObject::connect(&port, static_cast<void(QSerialPort::*)(QSerialPort::SerialPortError)>(&QSerialPort::error),
        [&](QSerialPort::SerialPortError err) {
            qDebug() << "Port error:" << err << port.errorString();
        });
        QObject::connect(&port, &QSerialPort::readyRead, [&]() {
            qDebug() << "Ready read notification";
        });
    
        QString name = "ttyUSB0";
        if (argc > 1)
            name = argv[argc-1];
    
        QObject::connect(&tmr, &QTimer::timeout, [&]() {
            if (! port.isOpen()) {
                port_open(name);
                return;
            }
            port.write("FOO BAR\r\n");
            auto bytes = port.bytesAvailable();
            qDebug() << "Read size:" << bytes;
            if (bytes > 0)
                qDebug() << "Read:" << port.readAll();
        });
    
        tmr.start(2000);
    
        return a.exec();
    }
    

    I compile this and create two connected virtual ports via socat. Then I connect to one of them via minicom (could be anything) and to the other with above program (port name is taken from the command arg). Then on minicom I see program output (so write() correctly pushes data through the pipe) but when I write in minicom I see no data received on the program side. Here's the output from program:

    $ ../RSComm pts/16
    Port error: 0 "Unknown error"
    Read size: 0
    Port error: 8 "Inappropriate ioctl for device"
    Port error: 8 "Inappropriate ioctl for device"
    Port error: 8 "Inappropriate ioctl for device"
    Port error: 9 "Resource temporarily unavailable"
    Read size: 0
    Read size: 0
    Read size: 0
    Read size: 0
    [...]
    Read size: 0
    

    For the record, this works in Windows (my larger program too - tested using com0com) and communication via socat (example call below) is working perfectly between two instances of minicom so the most probable source of problem is some change in Qt (unless there was some subtle change of system that caused problem to Qt but not to minicom but I doubt that).
    On Linux I see following transmission going via socat - again "FOO BAR\r\n" is sent from program and it goes through socat to minicom where I see it, but anything written in minicom (visible below) does not go to the QSerialPort:

    $ socat -v -d -d PTY,raw,echo=0,b115200,cs8 PTY,raw,echo=0,b115200,cs8
    2015/10/05 10:55:43 socat[9045] N PTY is /dev/pts/16
    2015/10/05 10:55:43 socat[9045] N PTY is /dev/pts/18
    2015/10/05 10:55:43 socat[9045] N starting data transfer loop with FDs [3,3] and [5,5]
    > 2015/10/05 10:55:50.956737  length=9 from=0 to=8
    FOO BAR\r
    > 2015/10/05 10:55:52.875832  length=9 from=9 to=17
    FOO BAR\r
    [...]
    > 2015/10/05 10:56:14.876608  length=9 from=108 to=116
    FOO BAR\r
    < 2015/10/05 10:56:15.608220  length=1 from=0 to=0
    L< 2015/10/05 10:56:15.689087  length=1 from=1 to=1
    A< 2015/10/05 10:56:15.941809  length=1 from=2 to=2
    A< 2015/10/05 10:56:16.292852  length=1 from=3 to=3
    \r> 2015/10/05 10:56:16.875822  length=9 from=117 to=125
    FOO BAR\r
    < 2015/10/05 10:56:18.025169  length=1 from=4 to=4
    A< 2015/10/05 10:56:18.241300  length=1 from=5 to=5
    L< 2015/10/05 10:56:18.449940  length=1 from=6 to=6
    A< 2015/10/05 10:56:18.785332  length=1 from=7 to=7
    \r> 2015/10/05 10:56:18.876030  length=9 from=126 to=134
    FOO BAR\r
    < 2015/10/05 10:56:19.883453  length=1 from=8 to=8
    A< 2015/10/05 10:56:20.060394  length=1 from=9 to=9
    L< 2015/10/05 10:56:20.254638  length=1 from=10 to=10
    A< 2015/10/05 10:56:20.666961  length=1 from=11 to=11
    \r> 2015/10/05 10:56:20.876227  length=9 from=135 to=143
    FOO BAR\r
    > 2015/10/05 10:56:22.876437  length=9 from=144 to=152
    FOO BAR\r
    > 2015/10/05 10:56:24.876635  length=9 from=153 to=161
    FOO BAR\r
    [...]
    

    I've grepped through change logs and in e54305ffde1f5e8d02687ce9ddae55f8128de32d I see some changes related to socat (I don't have real device ready at the moment so I'm reporting problems with the use of socat) but I gather that such communication through pts is still supported. Could anyone (@kuzulis ?) look at the problem? How can I debug this? Or maybe I'm missing something?

    Best regards
    Andrzej



  • "Resource temporarily unavailable"

    It is EAGAIN that interprets as ResourceError (it is a critical error) and the qtserialport disables a read notification.
    Most likelly it is an Ubuntu's bug: https://bugreports.qt.io/browse/QTBUG-48304

    Are you sure that you do not update a kernel? Please use other working kernel and try to use the "true" tty0tty driver instead of socat.

    UPD: You can check it by just open of a device (without connecting to readiRead() signal). If in this case will be triggered EAGAIN, this means that it is a kernel bug.



  • Seems to be as kuzulis wrote. I use Qt 5.5.0 in Ubuntu 14.04 LTS with the latest kernel (the previous kernels have been erased to save space....), thus I can't check using other kernels.



  • with the latest kernel

    What is latest kernel version? What is output with "uname -a" ?



  • kuzulis - thank you! You've pin pointed the problem perfectly.

    Are you sure that you do not update a kernel? Please use other working kernel and try to use the "true" tty0tty driver instead of socat.

    Yes I did, and now I've downgraded to previous kernel (*-63) and everything works as expected. Well, I said:

    unless there was some subtle change of system that caused problem to Qt but not to minicom but I doubt that

    and that happened to be the case (reminder to myself - trust Qt more and Ubuntu less :P).
    Just out of my curiosity - why tty0tty (kernel module) is preferred over socat?

    Best regards
    Andrzej



  • Me too!
    Downgrade from Kernel 3.13.0-65 to 3.13.0-63: problem solved.
    Thanks kuzulis
    Regards
    Paolo



  • Just out of my curiosity - why tty0tty (kernel module) is preferred over socat?

    Because on my practice with Socat && QtSerialPort (when are used the auto tests) I faced with a problems with Socat. For example, it can not re-open the created ttySxx links, and need to re-create it, re-run Socat and so on (maybe I do something wrong, I don't know). So, now I use tty0tty instead for auto-tests and all fine for me now. :)



  • With the latest kernel 3.13.0-66 problem solved. Thus, correction related to problem in version 3.13.0-64 and 3.3.0-65 is done.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.