Authors Top

If you have a few years of experience in the Linux ecosystem, and you’re interested in sharing that experience with the community, have a look at our Contribution Guidelines.

1. Overview

In this article, we’ll discuss ways to find all the serial devices on Linux without the need of opening them. This will show the devices that a system has, which is useful when diagnosing it or when setting up a new device.

2. Problem Statement

The /dev/ directory contains a file for each one of the devices of any given system. For serial devices, we’ll restrict ourselves to those that support both baud rates and the RTS/CTS flow control, which stands for Request-to-Send/Clear-to-Send under the RS-232 telecommunications standard.

We don’t want to open the devices as this can take a while and potentially return an error. When trying to open a device, a connection attempt is performed. An example of this behavior occurs for serial devices provided through Bluetooth when the driver of the system wants to connect the device.

3. Solutions

We’ll cover four solutions to the problem stated before, by looking at different files and using several tools.

3.1. /sys/class/ Directory

The filesystem under the /sys/class/ directory provides information about devices connected to a system. Inside it, the directory /sys/class/tty shows the serial devices, virtual terminals, and pseudo terminals, having subdirectories for specific serial device groups.

For example, let’s get the serial USB devices:

$ ls /sys/class/tty/ttyUSB*
/sys/class/tty/ttyUSB0
/sys/class/tty/ttyUSB1

If we access one of the directories for one of the devices, we see different files:

$ ls /sys/class/tty/ttyUSB0/
dev
device
power
subsystem
uevent

The file that states that we’re dealing with a serial device (and not with terminals) is the device/driver. Thus, we can examine only those devices that have those directory trees:

$ ls /sys/class/tty/*/device/driver
/sys/class/tty/ttyS0/device/driver
/sys/class/tty/ttyS1/device/driver
/sys/class/tty/ttyUSB0/device/driver
/sys/class/tty/ttyUSB1/device/driver

One naive and erroneous approach is to iterate only over the /dev/ttyS* directories, as we can also reach serial devices through other interfaces. With a USB to RS-232 adapter, the serial devices are under /dev/ttyUSB*, as in the example. Similarly, other namespaces may contain other serial devices.

3.2. dmesg Tool

With the dmesg tool, we can display on the screen the log of the kernel, which stores all the information produced by the drivers of the devices connected to a system. We have to search in the whole message buffer from dmesg, the serial devices we’re interested in:

$ dmesg | grep tty

We may need to execute the previous command with superuser rights.

3.3. HAL Software

The Hardware Abstraction Layer (HAL) is a tool that has been deprecated in favor of udev. However, the tool can still be found on the older Linux releases from before 2008, which are also those that most commonly happen to have the old serial interface standard.

We can obtain from all the available ports those that are capable of serial transfer:

$ hal-find-by-capability --capability serial

This returns a list of the unique device identifiers. We can plug the UDI value in:

$ hal-get-property --udi UDI --key serial.device

If we want to explore all serial devices, we can couple the two commands with a for loop:

$ for device in $(hal-find-by-capability --capability serial) ; do
hal-get-property --udi "${device}" --key serial.device
done

3.4. /dev/serial/ Directory

If we’re dealing with newer Linux kernels, the HAL tool is no longer available. However, we can take advantage of udev (as long as we have a release older than 2.5. installed).

Within the /dev/serial/ directories, there’s a list of all the serial ports that are available. They are symbolic links that point to the adequate /dev/ file. We find two groups of serial ports:

$ ls /dev/serial/
by-id/
by-path/

These two groups refer to the same serial ports, but they’re organized based on different information of the port. Let’s see what each one looks like:

$ ls -l /dev/serial/by-id/
total 0
lrwxrwxrwx 1 root root 13 2010-02-10 09:03 tty-WM_Gmbh._Serial_Controller-port0 -> ../../ttyS0
lrwxrwxrwx 1 root root 13 2010-02-10 09:03 tty-WM_Gmbh._Serial_Controller-port1 -> ../../ttyS1
lrwxrwxrwx 1 root root 13 2015-07-20 04:03 usb-PTechnology_Inc._USB-Serial_Controller-if00-port0 -> ../../ttyUSB0
lrwxrwxrwx 1 root root 13 2015-07-20 04:04 usb-PTechnology_Inc._USB-Serial_Controller-if00-port1 -> ../../ttyUSB1

For the path group, we have:

$ ls -l /dev/serial/by-path/
total 0
lrwxrwxrwx 1 root root 13 2010-02-10 09:03 pci-0000:00:0a.0-tty-1:1:1.0-port0 -> ../../ttyS0
lrwxrwxrwx 1 root root 13 2010-02-10 09:03 pci-0000:00:0a.0-tty-1:1:1.0-port1 -> ../../ttyS1
lrwxrwxrwx 1 root root 13 2015-07-20 04:03pci-0000:00:0b.0-usb-0:3:1.0-port0-> ../../ttyUSB0
lrwxrwxrwx 1 root root 13 2015-07-20 04:04 pci-0000:00:0b.0-usb-0:3:1.1-port1 -> ../../ttyUSB1

When there are no serial ports in a system, the /dev/serial/ directory is not present in the filesystem.

4. Conclusion

In this article, we’ve looked at four different ways to find all the available serial devices connected to a system. We did so without the need of opening the devices.

Authors Bottom

If you have a few years of experience in the Linux ecosystem, and you’re interested in sharing that experience with the community, have a look at our Contribution Guidelines.

Comments are closed on this article!