QSerialPortInfo::availablePorts() not calling availablePortsByFiltersOfDevices()
-
Hi,
I am running my QT application on an ARM device, trying to get all available serial ports.
Under my /sys/class/tty/ttyS0/ I have no "device" directory. The uevent file has DEVNAME=ttyS0 but has no DRIVER= line. Under /dev/ I have ttyS0 file that belongs to dialout group.
Because of lack of DRIVER=, inside availablePortsBySysfs(), in the for loop it hits a continue after an if check, and loop through the rest of the directories, finding that they all have no DRIVER=, and ends the loop, sets ok to true, returns an empty list of QSerialPortInfo. Because ok was left true, the 3rd option, availablePortsByFiltersOfDevices() never gets called.
Is this intended? Thanks in advance for any input.
-
Yes. The first viable means of identifying serial ports wins. The code found SYSFS and was able to search it for serial ports, which is what the ok == TRUE value indicates, further searches are not attempted. The previous search using udev will have returned ok == FALSE, which is why a SYSFS search has been attempted.
I assume you are looking because the code found no serial ports. Further assuming that there actually is a physical serial device, then the disconnect may be that the relevant driver is not present in the kernel.
-
Yes. The first viable means of identifying serial ports wins. The code found SYSFS and was able to search it for serial ports, which is what the ok == TRUE value indicates, further searches are not attempted. The previous search using udev will have returned ok == FALSE, which is why a SYSFS search has been attempted.
I assume you are looking because the code found no serial ports. Further assuming that there actually is a physical serial device, then the disconnect may be that the relevant driver is not present in the kernel.
@ChrisW67 Thank you. Indeed the code was not finding any serial ports. However I do not have a physical (conventionally 9-pin) serial port on this ARM device of mine, all I have is an audio jack used for UART, and can be connected by a UART to USB cable. In fact, the symlink of /sys/class/tty/ttyS0/ is pointing to /sys/devices/virtual/tty/ttyS0/ directory.
I suppose this would mean I only have virtual serial ports? I do have /dev/ptyp0 file present, but can QT find/use it? In this case what are my options? Thanks again.
-
@SanZ said in QSerialPortInfo::availablePorts() not calling availablePortsByFiltersOfDevices():
all I have is an audio jack used for UART, and can be connected by a UART to USB cable.
Sorry, not quite sure I follow. I think you mean you connect the ARM device using a 3.5mm plug, and that two-wire serial signal feeds into a USB-serial for the other end.
If the ARM board has a supported UART then it should be addressable through a /dev device and visible in /sys/class/tty somewhere regard of the physical interface (3.5mm jack, DB9 etc). You may have to do some other configuration to make it usable. On the RPi device, for example, the UART is already in use as the device system console and you need to disable this use.
https://raspberrypi.stackexchange.com/questions/96697/how-many-serial-ports-are-on-the-pi-3If the serial interface is actually provided to the ARM board by USB attached dongle then it would appear under /dev/ttyUSBx (driver support dependent). I would expect to see the device in
lsusboutput. Maybe a corresponding entry under /sys/class/tty: do know for sure, do not have a USB-serial device.
Once you find the device then you should be able address it directly from QSerialPort regardless of whether QSerialPortInfo finds it.As for pseudo-ttys, you may find this useful:
https://stackoverflow.com/questions/52187/virtual-serial-port-for-linux -
@SanZ said in QSerialPortInfo::availablePorts() not calling availablePortsByFiltersOfDevices():
all I have is an audio jack used for UART, and can be connected by a UART to USB cable.
Sorry, not quite sure I follow. I think you mean you connect the ARM device using a 3.5mm plug, and that two-wire serial signal feeds into a USB-serial for the other end.
If the ARM board has a supported UART then it should be addressable through a /dev device and visible in /sys/class/tty somewhere regard of the physical interface (3.5mm jack, DB9 etc). You may have to do some other configuration to make it usable. On the RPi device, for example, the UART is already in use as the device system console and you need to disable this use.
https://raspberrypi.stackexchange.com/questions/96697/how-many-serial-ports-are-on-the-pi-3If the serial interface is actually provided to the ARM board by USB attached dongle then it would appear under /dev/ttyUSBx (driver support dependent). I would expect to see the device in
lsusboutput. Maybe a corresponding entry under /sys/class/tty: do know for sure, do not have a USB-serial device.
Once you find the device then you should be able address it directly from QSerialPort regardless of whether QSerialPortInfo finds it.As for pseudo-ttys, you may find this useful:
https://stackoverflow.com/questions/52187/virtual-serial-port-for-linux@ChrisW67 said in QSerialPortInfo::availablePorts() not calling availablePortsByFiltersOfDevices():
Sorry, not quite sure I follow. I think you mean you connect the ARM device using a 3.5mm plug, and that two-wire serial signal feeds into a USB-serial for the other end.
This is exactly the case, sorry about the confusion.
If the ARM board has a supported UART then it should be addressable through a /dev device and visible in /sys/class/tty somewhere regard of the physical interface (3.5mm jack, DB9 etc).
Still a bit confused as how QT addresses it and uses/opens it. Under /dev/ I have ttyS0, ttyS1, ttyp0 and ttyp1 files, under /sys/class/tty/ I have these same 4 names as symlinks to directories(/sys/devices/virtual/tty/tty*/). Right now QSerialPortInfo is not recognizing them because no DRIVER= is in the uevent file.
You may have to do some other configuration to make it usable
If I do this, would QSerialPortInfo then be able to recognize the port? Or I would be able to have QSerialPort address and use it directly without QSerialPort finding it?
I will try to read and learn about this at the mean time, but I do really appreciate your patience and help here, thank you.
-
@ChrisW67 said in QSerialPortInfo::availablePorts() not calling availablePortsByFiltersOfDevices():
Sorry, not quite sure I follow. I think you mean you connect the ARM device using a 3.5mm plug, and that two-wire serial signal feeds into a USB-serial for the other end.
This is exactly the case, sorry about the confusion.
If the ARM board has a supported UART then it should be addressable through a /dev device and visible in /sys/class/tty somewhere regard of the physical interface (3.5mm jack, DB9 etc).
Still a bit confused as how QT addresses it and uses/opens it. Under /dev/ I have ttyS0, ttyS1, ttyp0 and ttyp1 files, under /sys/class/tty/ I have these same 4 names as symlinks to directories(/sys/devices/virtual/tty/tty*/). Right now QSerialPortInfo is not recognizing them because no DRIVER= is in the uevent file.
You may have to do some other configuration to make it usable
If I do this, would QSerialPortInfo then be able to recognize the port? Or I would be able to have QSerialPort address and use it directly without QSerialPort finding it?
I will try to read and learn about this at the mean time, but I do really appreciate your patience and help here, thank you.
After taking more look at QSerialPort source code, I see that if I set the port name(let's say ttyS9) directly via QSerialPort, instead of setting it to a QSerialPortInfo object and pass this object to QSerialPort to configure, then when open() is called, QT will use the name ttyS9 and look for it under /dev/.
If I go through QSerialInfo, QT will not look under /dev/ for the reason I described in my original post above, and fail at
descriptor = qt_safe_open(systemLocation.toLocal8Bit().constData(), flags);line in QSerialPortPrivate::open(...) function, because systemLocation is empty, and give "No such file or directory" system error which is what I was getting.
I will try tomorrow to skip QSerialPortInfo and use QSerialPort directly, hopefully this'll give me some positive result.
-
@ChrisW67 said in QSerialPortInfo::availablePorts() not calling availablePortsByFiltersOfDevices():
Sorry, not quite sure I follow. I think you mean you connect the ARM device using a 3.5mm plug, and that two-wire serial signal feeds into a USB-serial for the other end.
This is exactly the case, sorry about the confusion.
If the ARM board has a supported UART then it should be addressable through a /dev device and visible in /sys/class/tty somewhere regard of the physical interface (3.5mm jack, DB9 etc).
Still a bit confused as how QT addresses it and uses/opens it. Under /dev/ I have ttyS0, ttyS1, ttyp0 and ttyp1 files, under /sys/class/tty/ I have these same 4 names as symlinks to directories(/sys/devices/virtual/tty/tty*/). Right now QSerialPortInfo is not recognizing them because no DRIVER= is in the uevent file.
You may have to do some other configuration to make it usable
If I do this, would QSerialPortInfo then be able to recognize the port? Or I would be able to have QSerialPort address and use it directly without QSerialPort finding it?
I will try to read and learn about this at the mean time, but I do really appreciate your patience and help here, thank you.
@SanZ The special files /dev/ttyS0 etc. can exist (see
mknod) even if there is no device claiming them. My Linux desktop box, for example, has ttyS0 through ttyS31 but at most one active serial port UART (16550A or equivalent). The special file presence alone is not sufficient; a driver in the kernel needs to own the device matching the special file major and minor device numbers. In modern systems these device files are auto-created by software like udev or systemd, often in response to system hardware detection or other events. In a built-from-scratch UNIX box you may only have the files that were manually created under /dev. You ARM device seems like it may be halfway.$ ls -l /dev/ttyS0 crw-rw---- 1 root dialout 4, 64 Aug 30 16:58 /dev/ttyS0 crw-rw---- 1 root dialout 4, 65 Aug 30 16:58 /dev/ttyS1 ^ ^ | | | +- minor number, which TTY +---- major number, from linux/major.h, TTY_MAJOR 4 -
@SanZ The special files /dev/ttyS0 etc. can exist (see
mknod) even if there is no device claiming them. My Linux desktop box, for example, has ttyS0 through ttyS31 but at most one active serial port UART (16550A or equivalent). The special file presence alone is not sufficient; a driver in the kernel needs to own the device matching the special file major and minor device numbers. In modern systems these device files are auto-created by software like udev or systemd, often in response to system hardware detection or other events. In a built-from-scratch UNIX box you may only have the files that were manually created under /dev. You ARM device seems like it may be halfway.$ ls -l /dev/ttyS0 crw-rw---- 1 root dialout 4, 64 Aug 30 16:58 /dev/ttyS0 crw-rw---- 1 root dialout 4, 65 Aug 30 16:58 /dev/ttyS1 ^ ^ | | | +- minor number, which TTY +---- major number, from linux/major.h, TTY_MAJOR 4@ChrisW67 Thank you. I am still trying to understand all this.
When I run $ ls -l /dev/ttyS0 I get
$ ls -l /dev/ttyS0 crw-rw---- 1 root dialout 4, 64 Jan 1 1970 /dev/ttyS0but not the second line for ttyS1. I then look at:
cat /proc/tty/driverswith one of lines in this file being
bcmserial /dev/ttyS 4 64-65 serialI am not sure if this is enough indication for presence of driver. Because there is no device/ directory under /sys/class/tty/ttyS0/ and not to mention /sys/class/tty/ttyS0/device/driver symlink. How would I be certain if my ARM device has the driver, i.e. what are the things to look at?
-
@ChrisW67 Thank you. I am still trying to understand all this.
When I run $ ls -l /dev/ttyS0 I get
$ ls -l /dev/ttyS0 crw-rw---- 1 root dialout 4, 64 Jan 1 1970 /dev/ttyS0but not the second line for ttyS1. I then look at:
cat /proc/tty/driverswith one of lines in this file being
bcmserial /dev/ttyS 4 64-65 serialI am not sure if this is enough indication for presence of driver. Because there is no device/ directory under /sys/class/tty/ttyS0/ and not to mention /sys/class/tty/ttyS0/device/driver symlink. How would I be certain if my ARM device has the driver, i.e. what are the things to look at?
Using QSerialPort->setPortName() directly instead of going through QSerialPortInfo has indeed done it. I also rebooted the device which may have helped by allowing the driver to be picked up.
Would like to thank @ChrisW67 for all the knowledge and explanations.
-
@ChrisW67 Thank you. I am still trying to understand all this.
When I run $ ls -l /dev/ttyS0 I get
$ ls -l /dev/ttyS0 crw-rw---- 1 root dialout 4, 64 Jan 1 1970 /dev/ttyS0but not the second line for ttyS1. I then look at:
cat /proc/tty/driverswith one of lines in this file being
bcmserial /dev/ttyS 4 64-65 serialI am not sure if this is enough indication for presence of driver. Because there is no device/ directory under /sys/class/tty/ttyS0/ and not to mention /sys/class/tty/ttyS0/device/driver symlink. How would I be certain if my ARM device has the driver, i.e. what are the things to look at?
@SanZ said in QSerialPortInfo::availablePorts() not calling availablePortsByFiltersOfDevices():
How would I be certain if my ARM device has the driver, i.e. what are the things to look at?
I say the chances were good. You may see reference to "bcmserial" in the kernel output during boot (
dmesg | egrep -i 'bcm|serial|tty'). Perhaps you will see a loaded module of that name (lsmod). I cannot immediately see something of that name in the kernel source, but it does exist elsewhere on the net and may have morphed into "bcm63xx_uart" in the current kernel. It is a Broadcom device.You've already discovered the fastest way to see if it works...
-
@SanZ said in QSerialPortInfo::availablePorts() not calling availablePortsByFiltersOfDevices():
How would I be certain if my ARM device has the driver, i.e. what are the things to look at?
I say the chances were good. You may see reference to "bcmserial" in the kernel output during boot (
dmesg | egrep -i 'bcm|serial|tty'). Perhaps you will see a loaded module of that name (lsmod). I cannot immediately see something of that name in the kernel source, but it does exist elsewhere on the net and may have morphed into "bcm63xx_uart" in the current kernel. It is a Broadcom device.You've already discovered the fastest way to see if it works...
@ChrisW67 Indeed the fasted way is just to try and see. I did not have access to the environment to try it when I posted my last question, so I figured I'd ask about identifying existence of driver beforehand just in case QSerialPort doesn't work when I do try. But luckily it worked.
I did learn a lot and have much to learn, thanks for all the help.