QSerialPort and port naming on Linux (Centos)
-
Hi,
I am just faced to problem of naming usb-serial ports on linux (Centos). I have application with two serial ports (one is usb-serial convertor and the second is rs485-usb) both based on FTDI232RL. Each device has specific productID (same vendorID). Problem is that devices are named dependend on order of plugging devices to the system. I tried to use symbolic names in udev rules as fallows.
@
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="f608",SYMLINK+="rs485"
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="f601",SYMLINK+="rs232"@But QSerialPort doesn't show me symbolic name. On the other hand I am able to connect via symbolic name in CuteCom, but not in QSerialPort resp. QSerialPortInfo.
I'd like to now how to have persisted port names, that will be availalble in QSerialPort.Thanks for each suggestions or advice in advance.
David -
QSerialPort uses only device names from standard "/dev" directory.
By design, use of SYMLINK isn't provided (because then it would be necessary to pick up analogs of SYMLINK and for other platforms like Windows, MacOSX). Also it complicates internal implementation.
You can use or a full path to the device in "/dev" directories, or short device name:
- /dev/ttyUSB0
- ttyUSB0
So if you will try to make so:
@
...
QString portName = "/My/Custom/Path";
port.setPortName(portName);
...
@Then internally, in a class, this name will be transformed to:
@
"/dev/My/Custom/Path"
@Thus, opening of port returns failure. You can try comment implementation of internal method portNameToSystemLocation() for the transformation prohibition.
UPD: In the future, for identification of USB devices into QSerialPortInfo is planned to enter a new method of receiving serial number of the device. Thus it will be possible to select the desirable device on its S/N irrespective of the numerical postfix of name. But there is the main problem what not all USB devices contain S/N. :)
UPD2: Stop! You can use Product Identifier to select desirable device (or 232 or 485) through QSerialPortInfo, like:
@
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
if (info.productIdentifier() == 0xF601) {
port232.open(info); // RS232
}
if (info.productIdentifier() == 0xF608) {
port485.open(info); // RS485
}
}
@ -
What is VID/PID printed out for:
bq. lsusb -v
from console/terminal for your FTDI chip?
bq. It is not probably related to productID.
Related!
-
I'dont paste whole output from lsusb here. But results are next. For both VID is 0x0403 (FTDI). RS485 converter has PID 0xF608 and general FTDI232RL (just chip on my custom board) has PID 0x6001, as you mentioned in sample code. I think all shoud be correct and as I expected here.
-
Ok, next:
-
Your QtSerialPort package is assembled with udev support or without udev support?
-
What VID/PID is displayed when try to print:
bq. udevadm info -a --name=/dev/ttyUSBx
where x - nubmer for each device?
I suspect that your QtSerialPort is compiled without Udev support. May you check it? What return the description(), manufacturer() methods of QSerialPortInfo class?
-
-
When I put the udevadm commands as you wrote I get all info about devices PID, VID etc.., all is correct.
But methods from QSerialPort return empty data (my own app and also your example for listing ports). So it is probably the reason as you wrote. Could you please write me how to rebuild QSerialPort with Udev?
Thank you -
See serialport-lib.pri :
@
...
unix {
CONFIG += link_pkgconfigpackagesExist(libudev) { DEFINES += HAVE_LIBUDEV PKGCONFIG += libudev }
}
...
@and
@
...
...
} else {
linux*:contains( DEFINES, HAVE_LIBUDEV ) {
LIBS += -ludev
}
}
}
@Thus, these macroses by default shall define correctly libudev packet (if it was setup in system). Possibly it is a bug, and these macroses (with using qmake) are mistaken in CentOS.
In any case try to comment out (or to delete) this macroses, and write only:
@
DEFINES += HAVE_LIBUDEV
LIBS += -ludev
@UPD: Good info about use pkgconfig: http://developer.nokia.com/Community/Wiki/Using_pkg-config_with_qmake
-
Oops. I'm sorry, I'm wrong. Macroses are correct! :)
You need to install a package systemd-devel (for latest Fedora), or analog for CentOS (or libudev-devel or systemd-devel, I don't know). :)
And re-build QtSerialPort.
-
Kuzulis, I did fallows:
Check if libudev is installed by pkg-config --list-all
I've got: libudev libudev - Library to access udev device information
I check if is added libudev when compiling
g++ -Wl,-O1 -Wl,-rpath,/opt/QtSDK/Desktop/Qt/4.8.1/gcc/lib -shared -Wl,-soname,libQtSerialPort.so.1 -o libQtSerialPort.so.1.0.0 qserialport.o qserialportinfo.o qttylocker_unix.o qserialport_unix.o qserialportinfo_unix.o -L/opt/QtSDK/Desktop/Qt/4.8.1/gcc/ lib -ludev -lQtCore -L/opt/QtSDK/Desktop/Qt/4.8.1/gcc/lib -lpthread
So I assume the QSerialPortInfo is correctly compiled with udev, but I am still unable to get VID or PID from QSerialPortInfo methods (Project what use QSerialPortInfo was also rebuilded). Do you have an idea what could be worng? -
Hmm.. It strange... FTDI chip is supported by QSerialPortInfo...
- You are setup "systemd-devel" package?
- Methods description(), manufacturer() returns is empty strings?
- Please try to open qtserialport.pro via QtCreator and see highlighting of #ifdef blocks to check udev support.
- Try to check in debugger availablePorts() method.. Maybe there a bug in QSerialPortInfo...