获取 Linux 系统上所有可用串行端口/设备列表的正确方法是什么?
也就是说,当我遍历/dev/
中的所有设备时,如何以经典的方式判断哪些是串口,即那些通常支持波特率和RTS/CTS流量的设备控制?
解决方案将用 C 编码。
我问是因为我使用的第三方库明显错误:它似乎只迭代 /dev/ttyS*
。问题在于,例如,USB 上的串行端口(由 USB-RS232 适配器提供),这些端口列在/dev/ttyUSB* 下。阅读 Serial-HOWTO at Linux.org ,我知道随着时间的推移还会有其他 namespace 。
所以我需要找到检测串口设备的官方方法。问题是似乎没有记录,或者我找不到。
我想一种方法是从 /dev/tty*
打开所有文件并在它们上调用一个特定的 ioctl()
,该文件仅在串行设备上可用。不过,这会是一个好的解决方案吗?
hrickards 建议查看“setserial”的来源。 它的代码完全符合我的想法:
首先,它打开一个设备:
fd = open (path, O_RDWR | O_NONBLOCK)
然后它调用:
ioctl (fd, TIOCGSERIAL, &serinfo)
如果该调用没有返回错误,那么它显然是一个串行设备。
我在 Serial Programming/termios 中发现了类似的代码,建议也添加O_NOCTTY
选项。
不过,这种方法存在一个问题:
当我在 BSD Unix(即 Mac OS X)上测试这段代码时,它运行良好。 但是,通过蓝牙提供的串行设备会导致系统(驱动程序)尝试连接到蓝牙设备,这需要一段时间才会超时返回错误。这是由于刚刚打开设备造成的。我可以想象类似的事情也会发生在 Linux 上——理想情况下,我不需要打开设备来确定它的类型。我想知道是否还有一种方法可以在不打开的情况下调用 ioctl
函数,或者以一种不会导致建立连接的方式打开设备?
我该怎么办?
最佳答案
/sys
文件系统应该包含大量信息供您探索。我的系统(2.6.32-40-generic#87-Ubuntu)建议:
/sys/class/tty
它为您提供系统已知的所有 TTY 设备的描述。一个精简的例子:
# ll /sys/class/tty/ttyUSB*
lrwxrwxrwx 1 root root 0 2012-03-28 20:43 /sys/class/tty/ttyUSB0 -> ../../devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.4/2-1.4:1.0/ttyUSB0/tty/ttyUSB0/
lrwxrwxrwx 1 root root 0 2012-03-28 20:44 /sys/class/tty/ttyUSB1 -> ../../devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3:1.0/ttyUSB1/tty/ttyUSB1/
点击以下链接之一:
# ll /sys/class/tty/ttyUSB0/
insgesamt 0
drwxr-xr-x 3 root root 0 2012-03-28 20:43 ./
drwxr-xr-x 3 root root 0 2012-03-28 20:43 ../
-r--r--r-- 1 root root 4096 2012-03-28 20:49 dev
lrwxrwxrwx 1 root root 0 2012-03-28 20:43 device -> ../../../ttyUSB0/
drwxr-xr-x 2 root root 0 2012-03-28 20:49 power/
lrwxrwxrwx 1 root root 0 2012-03-28 20:43 subsystem -> ../../../../../../../../../../class/tty/
-rw-r--r-- 1 root root 4096 2012-03-28 20:43 uevent
这里的 dev
文件包含以下信息:
# cat /sys/class/tty/ttyUSB0/dev
188:0
这是主要/次要节点。这些可以在 /dev
目录中搜索以获得用户友好的名称:
# ll -R /dev |grep "188, *0"
crw-rw---- 1 root dialout 188, 0 2012-03-28 20:44 ttyUSB0
/sys/class/tty
目录包含所有 TTY 设备,但您可能希望排除那些讨厌的虚拟终端和伪终端。我建议你只检查那些有 device/driver
条目的:
# ll /sys/class/tty/*/device/driver
lrwxrwxrwx 1 root root 0 2012-03-28 19:07 /sys/class/tty/ttyS0/device/driver -> ../../../bus/pnp/drivers/serial/
lrwxrwxrwx 1 root root 0 2012-03-28 19:07 /sys/class/tty/ttyS1/device/driver -> ../../../bus/pnp/drivers/serial/
lrwxrwxrwx 1 root root 0 2012-03-28 19:07 /sys/class/tty/ttyS2/device/driver -> ../../../bus/platform/drivers/serial8250/
lrwxrwxrwx 1 root root 0 2012-03-28 19:07 /sys/class/tty/ttyS3/device/driver -> ../../../bus/platform/drivers/serial8250/
lrwxrwxrwx 1 root root 0 2012-03-28 20:43 /sys/class/tty/ttyUSB0/device/driver -> ../../../../../../../../bus/usb-serial/drivers/ftdi_sio/
lrwxrwxrwx 1 root root 0 2012-03-28 21:15 /sys/class/tty/ttyUSB1/device/driver -> ../../../../../../../../bus/usb-serial/drivers/ftdi_sio/
https://stackoverflow.com/questions/2530096/