linux - 如何在不打开 Linux 的情况下找到所有串行设备(ttyS、ttyUSB、..)?

获取 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/

相关文章:

linux - 如何通过 * 将包括隐藏文件在内的所有文件移动到父目录中

linux - Java 进程列表

python - 如何为每个子图添加标题

linux - 从 ps -ef |grep 关键字获取 pid

c - [ N ... M ] 在 C 聚合初始值设定项中是什么意思?

python - 如何检查变量是否为具有 python 2 和 3 兼容性的字符串

python - 何时在 Python 中使用 %r 而不是 %s?

python - 如何检查浮点值是否为整数

python - 如何在 Windows 7 的命令提示符中运行 Python 程序?

linux - 如何从脚本编辑/etc/sudoers?