[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-48304Are 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.