获取Linux系统上所有可用串行端口/设备的列表的正确方法是什么?
换言之,当我在/dev/
中遍历所有设备时,如何用经典的方式区分哪些设备是串行端口,即那些通常支持波特率和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)
如果这个调用没有返回错误,那么它显然是一个串行设备。
我在Serial Programming/termios中发现了类似的代码,它建议还添加O_NOCTTY
选项。
不过,这种方法有一个问题:
当我在BSD Unix(即Mac OS X)上测试这段代码时,它也能正常工作。但是,通过蓝牙提供的串行设备会导致系统(驱动程序)尝试连接到蓝牙设备,这需要一段时间才能返回并显示超时错误。这是由于刚刚打开设备造成的。我可以想象在Linux上也会发生类似的事情-理想情况下,我不需要打开设备来确定它的类型。我想知道是否还有一种方法可以在不打开的情况下调用ioctl
函数,或者以不会导致建立连接的方式打开设备?
我该怎么办?
/sys
文件系统应该为您的任务包含大量信息。我的系统(2.6.32-40-generic#87 Ubuntu)建议:它提供了系统已知的所有TTY设备的描述。精简示例:
以下链接之一:
这里的
dev
文件包含以下信息:这是主要/次要节点。可以在
/dev
目录中搜索这些名称以获取用户友好的名称:目录包含所有TTY设备,但是您可能希望排除那些讨厌的虚拟终端和伪终端。我建议您只检查那些有
device/driver
项的:在最近的内核(不确定从什么时候开始)中,您可以列出/dev/serial的内容以获得系统上串行端口的列表。它们实际上是指向正确/dev/节点的符号链接:
如你所见,这是一个USB串行适配器。注意,当系统上没有串行端口时,/dev/serial/目录不存在。希望这有帮助:)。
我正在做如下代码。它适用于USB设备和愚蠢的串行8250设备,我们都有30个-但只有两个真正的工作。
基本上我使用的概念来自以前的答案。首先枚举/sys/class/tty/中的所有tty设备。不包含/device subdir的设备将被过滤掉。/sys/class/tty/console就是这样一个设备。然后根据驱动程序symlink fx的目标,实际包含设备的设备被接受为有效串行端口。
对于ttyS0
serial8250驱动的所有驱动程序都必须是使用前面提到的ioctl的探测程序。
只有报告有效设备类型的端口才有效。
枚举串行端口的完整源如下所示。欢迎添加。
相关问题 更多 >
编程相关推荐