4

I want to write on a serial device. Unfortunately I have the feeling the QSerialPort is not properly implemented under linux. In contrast to other methods (python) I get !sometimes! a hang of the program when I try to call:

serial.open(QIODevice::ReadWrite)

I am using the example from http://qt-project.org/wiki/QtSerialPort (see below). The QSerialPortInfo is working properly so that I can search for my device before I open it. The problem appeared in all Qt 5.* series. I am currently using 5.3 beta from the OpenSuse repository. Other tools or methods proof, that the device is working (Windows or 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();
}

Working python script:

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

Edit: I tested with debugger. Seems to be a problem of Qt 5 at least with linux. It looks like connected with a device lock.

dgrat
  • 2,214
  • 4
  • 24
  • 46
  • What do you mean by QSerialDevice? There is no such a class! Do the exmaples work for you? – László Papp Apr 05 '14 at 22:06
  • 1
    No the examples only work sometimes on my systems (OpenSuse) with several Qt versions. PySerial works always (windows, linux). Wonder actually whether it is just me or whether it is just Qt problem. However if it is not hanging with QSerialPort then everything is smooth. – dgrat Apr 05 '14 at 22:12
  • Which example are you talking about? Have you tried to command line readers and writers? Which Qt version are you using? Perhaps you are using an outdated QtSerialPort? Where did you get it from? What type of serialport exactly are you using? – László Papp Apr 05 '14 at 22:14
  • 1
    I use the 5.30 beta packages, the same problems I had with 5.2.1. – dgrat Apr 05 '14 at 22:16
  • Please answer all the questions. Also, does the info class print out everything correctly as expected? – László Papp Apr 05 '14 at 22:17
  • 1
    The info class works perfectly always. I can determine all devices. – dgrat Apr 05 '14 at 22:44
  • Please answer the rest of the questions I asked. They are important to know. – László Papp Apr 06 '14 at 03:24
  • @lpapp Clearly they are not. Your "clarifying" questions read more like haranguing. – Kyle Strand May 23 '16 at 23:22

2 Answers2

5

I don't know what Mr. Papp is complaining about; I was able to reproduce your problem without any more information.

On Linux, if the Qt process with an open QSerialPort instance terminates abnormally or the QSerialPort instance is otherwise not destroyed upon process exit, then the lock file hangs around and can cause a problem. A stale lock file shouldn't cause this problem; the lock file contains the crashed application's PID, and the new application instance should recognize that no process with that PID exists and delete the lock immediately before creating a new one. strace will show you the lock file in question repeatedly with increasing backoff time as the new process repeatedly checks to see if the stale lock file has been deleted or whatever. So, delete the file (for example, /var/lock/LCK..ttyS0); you will own the lock file if you ran the application that crashed.

A random side note: if you are using QSerialPort in Python through PyQt5 (which does work, by the way!), be sure you have explicitly deleted the QSerialPort instance before the Python interpreter exits. If you're manipulating the port in IPython, then do "%xdel portobject" before exiting.

It's a dumb workaround, but provided you are using some other mechanism to ensure that you don't have two instances of your program running and using the same port - or if you simply don't care - you could have a line of code delete that lock file before opening the port.

IMHO, Qt shouldn't be emulating completely worthless Windows style nanny state protections in the first place. I can sudo rm -rf / and it happens! I can even rm the serial port. Given such unfettered, primal, god like power, I should be able to open a serial port whenever and however I please...

Erik Hvatum
  • 301
  • 3
  • 7
  • Yeah, if I delete the lock file, then I can access it again. Unfortunately I don't know why there is already a lock file sometimes directly after a reboot. – dgrat May 26 '14 at 12:51
  • Where are these lock files located? – Goddard Apr 17 '16 at 23:11
  • Re: "Qt shouldn't be emulating completely worthless Windows style nanny state protections in the first place." These protections also make debugging harder; for instance, [I discovered that running my application as root (and improperly exiting) prevented re-running it as a non-root user, but I was mystified that `echo foo >> /dev/` still worked.](http://stackoverflow.com/q/37335986/1858225) – Kyle Strand May 23 '16 at 23:12
  • @Goddard As mentioned at the end of the second paragraph, they're in `/var/lock`, and the name of the file indicates the device that is locked. – Kyle Strand May 23 '16 at 23:13
  • This is [considered a bug](https://bugreports.qt.io/browse/QTBUG-36983), at least by some users. In that thread it's acknowledged that the problem would be solved by giving the lock-file `666` permissions. – Kyle Strand May 23 '16 at 23:23
  • Oh, and finally, the behavior has changed (in 5.5.1 or earlier) so that it now gives a permissions error rather than hanging. – Kyle Strand May 23 '16 at 23:25
  • This will be fixed in the 5.6.2 release: https://bugreports.qt.io/browse/QTBUG-36983 – Kyle Strand Sep 16 '16 at 18:26
3

The class tries to obtain lock for serial port. Line lockFileScopedPointer->lock(); in bool QSerialPortPrivate::open(QIODevice::OpenMode mode) Probably the application was run as root and the lock file is inaccessible when the application is run as different user. Run strace to check.

grzegorz
  • 331
  • 3
  • 16
  • The problem is partly in the implementation of the file lock and maybe also a problem of my distribution. Unfortunately not so easy to reproduce 100%. – dgrat May 14 '14 at 07:53