我需要在Linux上测试一个串口应用程序,但是我的测试机只有一个串口。

有没有办法向 Linux 添加虚拟串行端口并通过 shell 或脚本模拟设备来测试我的应用程序?

笔记:我无法重新映射端口,它在 ttys2 上硬编码,我需要在编写应用程序时对其进行测试。

有帮助吗?

解决方案

为此,您可以使用 pty(“伪电传打字机”,其中串行端口是“真正的电传打字机”)。从一端开始,打开 /dev/ptyp5, ,然后将您的程序附加到 /dev/ttyp5; ttyp5 将像串行端口一样工作,但将通过 /dev/ptyp5 发送/接收它所做的一切。

如果你确实需要它来与一个名为 /dev/ttys2, ,然后只需移动您的旧 /dev/ttys2 让开并创建一个符号链接 ptyp5ttys2.

当然,您可以使用除 ptyp5. 。也许选择一个数字较大的一个以避免重复,因为您的所有登录终端也将使用 ptys。

维基百科有更多关于 ptys 的信息: http://en.wikipedia.org/wiki/Pseudo_terminal

其他提示

补充@slonik的答案。

您可以执行以下步骤来测试 socat 创建虚拟串行端口(在 Ubuntu 12.04 上测试):

打开一个终端(我们称之为终端 0)并执行它:

socat -d -d pty,raw,echo=0 pty,raw,echo=0

上面的代码返回:

2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/2
2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/3
2013/11/01 13:47:27 socat[2506] N starting data transfer loop with FDs [3,3] and [5,5]

打开另一个终端并写入(终端 1):

cat < /dev/pts/2

该命令的端口名称可以根据PC改变。这取决于之前的输出。

2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/**2**
2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/**3**
2013/11/01 13:47:27 socat[2506] N starting data transfer loop with FDs 

您应该使用突出显示区域中可用的号码。

打开另一个终端并写入(终端 2):

echo "Test" > /dev/pts/3

现在返回到 1 号航站楼,您将看到字符串“Test”。

为此使用 socat:

例如:

socat PTY,link=/dev/ttyS10 PTY,link=/dev/ttyS11

还有tty0tty http://sourceforge.net/projects/tty0tty/ 这是一个真正的 Linux 零调制解调器模拟器。

它是一个简单的内核模块——一个小的源文件。我不知道为什么它在 sourceforge 上只受到了反对,但它对我来说效果很好。它最好的一点是它还可以模拟硬件引脚(RTC/CTS DSR/DTR)。它甚至实现了 TIOCMGET/TIOCMSET 和 TIOCMIWAIT iotcl 命令!

在最新的内核上,您可能会遇到编译错误。这很容易解决。只需在 module/tty0tty.c 源代码的顶部插入几行(在包含之后):

#ifndef init_MUTEX
#define init_MUTEX(x) sema_init((x),1)
#endif

当模块加载时,它会创建 4 对串行端口。这些设备是 /dev/tnt0 到 /dev/tnt7,其中 tnt0 连接到 tnt1,tnt2 连接到 tnt3,等等。您可能需要修复文件权限才能使用这些设备。

编辑:

我想我的热情有点快了。虽然该驱动程序看起来很有前途,但它似乎不稳定。我不确定,但我认为它使我在家工作的办公室里的一台机器崩溃了。周一回到办公室之前我无法查看。

第二件事是 TIOCMIWAIT 不起作用。该代码似乎是从一些“tiny tty”示例代码复制的。TIOCMIWAIT 的处理似乎到位,但它永远不会唤醒,因为缺少对wake_up_interruptible() 的相应调用。

编辑:

办公室发生的车祸确实是司机的错。缺少初始化,完全未经测试的 TIOCMIWAIT 代码导致机器崩溃。

我昨天和今天都重写了驱动程序。有很多问题,但现在对我来说效果很好。由驱动程序管理的硬件流控制仍然缺少代码,但我不需要它,因为我将使用用户模式代码中的 TIOCMGET/TIOCMSET/TIOCMIWAIT 自己管理引脚。

如果有人对我的代码版本感兴趣,请给我留言,我会将其发送给您。

您可能想看看 蒂博VSPDL 用于使用内核驱动程序创建 Linux 虚拟串行端口——它看起来很新,并且现在可以下载(测试版)。目前不确定许可证,或者他们是否只想在未来将其商业化。

还有其他商业替代品,例如 http://www.ttyredirector.com/.

在开源中, 雷姆串行 (GPL) 也可以使用 Unix PTY 做你想做的事。它将“原始形式”的串行数据传输到网络套接字;创建端口时必须完成类似 STTY 的终端参数设置,稍后更改它们(如 RFC 2217 中所述)似乎不受支持。您应该能够运行两个 remserial 实例来创建像 com0com 这样的虚拟 nullmodem,但您需要提前设置端口速度等。

索卡特 (也是 GPL)就像 Remserial 的扩展变体,具有更多选项,包括用于将 PTY 重定向到其他内容的“PTY”方法,该方法可以是 Socat 的另一个实例。对于 Unit tets,socat 可能比 remserial 更好,因为您可以直接将文件放入 PTY 中。请参阅 PTY 示例 在联机帮助页上。A 补丁存在 在“contrib”下为协商串行线路设置提供 RFC2217 支持。

使用之前答案中发布的链接,我使用虚拟串行端口在 C++ 中编写了一个小示例。我把代码推送到了GitHub: https://github.com/cymait/virtual-serial-port-example .

该代码非常不言自明。首先,通过运行 ./main master 创建主进程,它将打印到设备正在使用的 stderr。之后,调用 ./main 从设备,其中 device 是第一个命令中打印的设备。

就是这样。两个进程之间有双向链接。

使用此示例,您可以通过发送各种数据来测试应用程序,并查看它是否正常工作。

此外,您始终可以对设备进行符号链接,因此无需重新编译正在测试的应用程序。

您可以使用 USB->RS232 适配器吗?我有一些,他们只使用 FTDI 驱动程序。然后,您应该能够将 /dev/ttyUSB0 (或创建的任何内容)重命名为 /dev/ttyS2 。

我可以想到三个选择:

实施 RFC 2217

RFC 2217 涵盖 TCP/IP 标准的 com 端口,允许一个系统上的客户端模拟本地程序的串行端口,同时透明地向另一个系统上实际具有串行端口的服务器发送和接收数据和控制信号。这是一个 高层概述.

您要做的就是找到或实现一个客户端 com 端口驱动程序,该驱动程序将在您的 PC 上实现系统的客户端 - 看起来是一个真正的串行端口,但实际上将所有内容传送到服务器。您可以从 Digi、Lantronix 等公司免费获得此驱动程序,以支持他们真正的独立串口服务器。

然后,您可以在另一个程序中本地实现连接的服务器端 - 允许客户端连接并根据需要发出数据和控制命令。

这可能并不简单,但 RFC 就在那里,您也许能够找到一个实现连接一侧或两侧的开源项目。

修改linux串口驱动

或者,Linux 的串行端口驱动程序源也很容易获得。以此为基础,对硬件控制部分进行内部处理,并让一个驱动程序运行两个 /dev/ttySx 端口,作为一个简单的环回。然后将您的真实程序连接到 ttyS2,将模拟器连接到另一个 ttySx。

在环回中使用两根 USB<-->串行电缆

但现在最容易做的事情是什么?花 40 美元购买两个串行端口 USB 设备,将它们连接在一起(空调制解调器),实际上有两个真正的串行端口 - 一个用于您正在测试的程序,一个用于您的模拟器。

-亚当

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top