我需要在Linux上测试一个串口应用,但是,我的测试机器只有一个串口。
有没有办法在Linux上添加一个虚拟串口,通过shell或脚本模拟设备来测试我的应用程序?
注意:我不能重新映射端口,它硬编码在ttys2上,我需要测试应用程序的编写。
补充一下@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
这个命令的端口名称可以根据电脑来改变,它取决于前面的输出。
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"。
link=/path/to/link
(在echo=0后)。因此,它可以被用于自动测试。(正如slonik在他们的答案中所做的那样) socat -d -d pty,raw,echo=0 /dev/ttyUSB5,raw,echo=0
. /dev/ttyS0
而不是 /dev/pts/1
的串口吗?
你可以使用pty("伪电传",而串口是 "真电传")来做这个。 从一端打开 /dev/ptyp5
,然后将你的程序连接到 /dev/ttyp5
; ttyp5
将像串口一样行动,但将通过/dev/ptyp5发送/接收它所做的一切。
如果你真的需要它与一个叫做 /dev/ttys2
的文件对话,那么只要将你原来的 /dev/ttys2
移开,从 ptyp5
到 ttys2
做一个符号链接。
当然,你可以使用 ptyp5
以外的一些数字。
维基百科有更多关于ptys的内容: http://en.wikipedia.org/wiki/Pseudo_terminal
pts
man page 。 用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命令。
在最近的内核上,你可能会出现编译错误。这很容易解决。只要在模块/tty0tty.c源代码的顶部插入几行(在includes之后)。
#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自己管理引脚。
如果有人对我的代码版本感兴趣,给我发个信息,我就把它发给你。
你可能想看看 Tibbo VSPDL ,用内核驱动创建一个Linux虚拟串口 -- 它似乎很新,而且现在可以下载(测试版)。目前还不清楚许可证的情况,也不知道他们是否想在将来把它作为商业用途。
还有其他的商业替代品,比如 http://www.ttyredirector.com/ 。
在开放源码中, Remserial (GPL)也可能做你想做的事,使用Unix PTY的。它将串行数据以 "原始形式 "传输到网络套接字;类似于STTY的终端参数设置必须在创建端口时完成,像RFC 2217中描述的那样随后改变它们似乎并不被支持。你应该能够运行两个remserial实例来创建一个像com0com一样的虚拟空模,只是你需要提前设置端口速度等。
Socat (也是GPL)就像Remserial的一个扩展变体,有很多很多的选项,包括一个将PTY重定向到其他东西的 "PTY "方法,它可以是Socat的另一个实例。对于Unit tets来说,Socat可能比Remserial更好,因为你可以直接把文件猫到PTY中。见manpage上的 PTY例子 。在 "contrib "下有一个 补丁 ,为协商串行线设置提供RFC2217支持。
利用前面答案中的链接,我用C++编写了一个使用虚拟串口的小例子。我把代码推送到GitHub。 https://github.com/cymait/virtual-serial-port-example .
该代码是不言自明的。首先,你通过运行./main master创建主进程,它将把设备的使用情况打印到stderr。之后,你调用./main slave device,其中device是第一个命令中打印的设备。
就这样了。你在两个进程之间有了一个双向的链接。
使用这个例子,你可以通过发送各种数据来测试你的应用程序,看看它是否工作正常。
另外,你可以随时对设备进行符号连接,所以你不需要重新编译你正在测试的应用程序。
<unistd.h>
。另外还有一堆不应该忽略的警告,可以修复的东西,但总的来说,我喜欢简单的代码。 你能不能用一个USB->RS232适配器?我有几个,它们只是使用FTDI的驱动程序。然后,你应该能够将/dev/ttyUSB0(或任何被创建的)重命名为/dev/ttyS2。
我可以想到三种选择:
RFC 2217 涵盖了一个com port to TCP/IP标准,它允许一个系统上的客户端模拟本地程序的串口,同时透明地发送和接收数据和控制信号到另一个系统上的服务器,该系统实际上拥有串口。 下面是一个 高层次的概述 。
你要做的是找到或实现一个客户端COM端口驱动程序,它将在你的PC上实现系统的客户端--看起来是一个真正的串行端口,但实际上是把所有东西都传送到服务器上。 你也许能从Digi、Lantronix等公司免费获得这种驱动程序,以支持他们真正的独立串口服务器。
然后你将在另一个程序中实现本地连接的服务器端--允许客户端连接并根据需要发布数据和控制命令。
这可能不是小事,但RFC就在那里,你也许能找到一个开源项目来实现连接的一个或两个方面。
另外,Linux的串口驱动源也很容易得到。 拿着它,去掉硬件控制部分,让这个驱动运行两个/dev/ttySx端口,作为一个简单的环回。 然后把你的真实程序连接到ttyS2上,把你的模拟器连接到另一个ttySx上。
但现在最容易做的事情是什么? 花40美元买两个串口USB设备,把它们连在一起(null modem),实际上有两个真正的串口--一个用于你测试的程序,一个用于你的模拟器。
-Adam
$ socat -d -d pty,link=/tmp/vserial1,raw,echo=0 pty,link=/tmp/vserial2,raw,echo=0
将为 /dev/pts/*
中生成的虚拟串行端口生成 /tmp/vserial1
和 /tmp/vserial2
的符号链接