获取Linux系统上所有可用串行端口/设备列表的正确方法是什么?

换句话说,当我迭代/dev/中的所有设备时,我如何以classic 的方式判断哪些设备是串行端口,也就是那些通常支持波特率和RTS/CTS流量控制的设备?

解决方案将用C编码.

我这样问是因为我使用的第三方库显然是错误的:它似乎只在/dev/ttyS*上迭代.问题是,例如,USB上有串行端口(由USB-RS232适配器提供),这些端口列在/dev/ttyUSB*下.读了这Serial-HOWTO at Linux.org个名字,我觉得随着时间的推移,还会有其他的名字空间.

所以我需要找到检测串行设备的官方方法.问题是似乎没有任何记录,或者我找不到.

我想其中一种方法是打开/dev/tty*中的所有文件,并调用仅在串行设备上可用的特定ioctl().不过,这是一个好的解决方案吗?

使现代化

hrickards建议查看"setserial"的来源.

首先,它打开一个具有以下功能的设备:

fd = open (path, O_RDWR | O_NONBLOCK)

然后它调用:

ioctl (fd, TIOCGSERIAL, &serinfo)

如果这个调用没有返回错误,那么显然是串行设备.

我在100中找到了类似的代码,建议也添加O_NOCTTY选项.

There is one problem with this approach, though:

When I tested this code on BSD Unix (that is, Mac OS X), it worked as well. However, serial devices that are provided through Bluetooth cause the system (driver) to try to connect to the Bluetooth device, which takes a while before it'll return with a timeout error. This is caused by just opening the device. And I can imagine that similar things can happen on Linux as well - ideally, I should not need to open the device to figure out its type. I wonder if there's also a way to invoke ioctl functions without an open, or open a device in a way that it does not cause connections to be made?

我该怎么办?

推荐答案

/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

这是主/次 node .可以在/dev目录中搜索这些名称,以获得用户友好的名称:

# ll -R /dev |grep "188, *0"
crw-rw----   1 root dialout 188,   0 2012-03-28 20:44 ttyUSB0

/sys/class/tty dir包含所有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/

Linux相关问答推荐

在c++编译期间,什么是linux命令,它给出了链接库的路径?

一个关于Linux中的fork()和物理地址的奇怪问题

从 ALSA USB 硬件设备获取 USB 设备文件路径

使用awk命令将以:分隔的两个文件合并的方法

为什么 `std::this_thread::yield()` 比 `std::this_thread::sleep_for(0s)` 慢 10 倍?

将所有列乘以一个常数

使用 sed 或 awk 格式化文本

为什么我在从 Linux 通过 telnet 发送 Ctrl-C 后停止接收数据?

如何用 Sed 替换 Match 后的 2 个连续行

如何从linux调度程序中屏蔽一个cpu(防止它调度线程到那个cpu上)?

如何使用多个版本的 GCC

将 awk 输出保存到变量

在 cron 作业(job)中执行 PHP 脚本

仅在不存在时添加换行符

scp 使用私钥身份验证将目录复制到另一台服务器

ldconfig 错误:使用 Linux 加载程序时不是符号链接

在 shell 脚本的 for 循环中迭代行而不是单词

后缀 - status=bounced(未知用户myuser)

如何始终以 GB 为单位获取 df linux 命令输出

libaio.so.1:无法打开共享对象文件