当前位置: 首页 > 面试题库 >

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

卢枫涟
2023-03-14
问题内容

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

换句话说,当我遍历中的所有设备时/dev/,如何以经典方式分辨哪些设备是串行端口,即那些通常支持波特率和RTS /
CTS
流控制的设备?

解决方案将用C编码。

我问是因为我正在使用第三方库,但这样做显然是错误的:它似乎仅在上进行迭代/dev/ttyS*。问题是,例如,存在USB上的串行端口(由USB-
RS232适配器提供),而这些端口在/ dev / ttyUSB
*下列出。在Linux.org上阅读Serial-HOWTO时,我发现随着时间的流逝,还将有其他名称空间。

因此,我需要找到检测串行设备的官方方法。问题是似乎没有文件记录在案,或者我找不到它。

我想一种方法是从中打开所有文件/dev/tty*并对其进行调用ioctl(),这些文件仅在串行设备上可用。但是,这将是一个好的解决方案吗?

更新资料

希拉克们 建议看看“ 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-通用#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/


 类似资料:
  • 与传统的提示用户进入设置页面并启用定位服务然后再次返回的方法不同,我发现在一些最新的应用程序中有一种更简单的方法可以做到这一点。 参考下面的屏幕截图,它会向用户提示一个对话框,只需单击一下即可启用定位服务,并且可以在这些应用程序中运行。 我如何才能实现同样的目标?

  • 问题内容: 我正在用JavaScript编写一些代码。在这段代码中,我想读取一个json文件。该文件将从URL加载。 如何在JavaScript的对象中获取此JSON文件的包含? 例如,这是我的JSON文件,位于: 我想像这样在我的文件中使用它: 问题答案: 这是一个不需要jQuery的示例: 称呼为:

  • 我想用.bat运行一个jar文件(jar文件似乎不想自己打开,但现在这是一个不同的问题),但由于Java文件运行了很长时间,命令提示符仍处于打开状态(而.bat/.jar仍在运行) 我不想这样。 我在某处读到可以使用.cmd文件和以下命令: 若要在没有命令提示符的情况下运行bat文件,请执行以下操作。但那对我不起作用。当我单击.cmd程序时,它只是打开一个命令promopt,并在循环中反复打印“c

  • 我的 Android 应用 (Java NDK) 报告了许多由0xdeadd00d导致的崩溃(信号)。众所周知,它是Dalvik VM中止的简写。这些都没有发生在我的JNI调用中,但信号处理发生在本地世界。但是,本机崩溃报告通常报告的内容(寄存器,堆栈)对于调试这些内容毫无用处。 有办法从原生信号处理程序到达Java调用栈吗?或者转储最近logcat活动的一部分?

  • 问题内容: 我从plist中的字典中加载了一个值,但是当我将其打印到控制台时,它会打印:Optional(Monday Title),而不仅仅是“ Monday Title”。 如何在打印时摆脱值的Optional()? 问题答案: 摆脱的一种方法是使用感叹号: 但是,只有在确定存在该值的情况下,才应这样做。另一种方法是解包和使用条件,例如: 将该程序粘贴到runswiftlang中进行演示:

  • 问题内容: 该代码选择同一文件夹中的所有xml文件,作为被调用的可执行文件,并以异步方式将处​​理应用于回调方法中的每个结果(在下面的示例中,仅打印文件名)。 如何避免使用sleep方法阻止main方法退出?我在解决问题时遇到了麻烦(我想这就是同步结果所必需的),因此,我们将不胜感激! 问题答案: 您可以使用sync.WaitGroup。引用链接的示例: