适用于Linux的虚拟串行端口


127

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

有没有一种方法可以通过在Shell或脚本中模拟设备来向Linux添加虚拟串行端口并测试我的应用程序?

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

Answers:


74

您可以为此使用pty(“ pseudo-teletype”,其中串行端口是“ real teletype”)。从一端打开/dev/ptyp5,然后将程序附加到/dev/ttyp5ttyp5就像串口一样,但是会通过/ dev / ptyp5发送/接收它所做的一切。

如果您真的需要它与名为的文件进行通讯/dev/ttys2,则只需将旧文件移开/dev/ttys2,并从ptyp5到符号链接ttys2

当然,您可以使用以外的其他数字ptyp5。也许选择一个数字较大的名称以避免重复,因为您的所有登录终端也将使用pty。

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


8
在Linux上,您可以使用openpty / forkpty系统调用。参见手册页
马修·史密斯

8
如何使用命令行工具创建虚拟串行端口对?
linjunhalida 2010年

8
请注意,许多串行端口参数(例如波特率,奇偶校验,硬件流控制,字符大小(?))未在pty中实现,因此,不可能在存在串行传输错误的情况下测试您的应用程序。
Dima Tisnek'4

10
这很有用,但是它描述了“旧式” BSD伪终端。“新样式”的UNIX 98伪终端的操作略有不同- 有关详细信息,请参见pts手册页
Craig McQueen 2012年

3
@LaszloPapp我很抱歉,我一直在撒谎
马修·史密斯

160

补充@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”。


这对我来说比slonik的答案更好,因为它会自动分配给虚拟COM端口文件,并且不会回显。
gbmhunter 2014年

7
如果要重现文件名,请link=/path/to/link在每个设备声明后使用(在echo = 0之后)。因此,它可以用于自动化测试。(就像slonik的回答一样)
Patrick B.

完全如前所述。这帮助了我,谢谢。
nim118

1
要创建链接到实际串行端口的pty :socat -d -d pty,raw,echo=0 /dev/ttyUSB5,raw,echo=0
Penghe Geng

我可以创建一个串行端口的名称,如/dev/ttyS0代替/dev/pts/1
MRID

48

为此请使用socat:

例如:

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

经minicom测试,这对我来说效果很好!似乎到一个端子的输入会回显到两个端子(因此它也会重新出现在输入端子上)。
gbmhunter 2014年

1
我没有相同的回声行为... minicom具有“本地回声”功能...但是当它被禁用时,它的工作原理与真实的串行端口完全相同。谢谢你的提示。
cptHammer

16

还有tty0tty http://sourceforge.net/projects/tty0tty/,它是Linux的真正的空调制解调器模拟器。

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

在最近的内核上,您可能会遇到编译错误。这很容易解决。只需在module / 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不起作用。该代码似乎是从某些“微小的tty”示例代码复制而来的。似乎已经对TIOCMIWAIT进行了处理,但是它从未唤醒,因为缺少了对ake_up_interruptible()的相应调用。

编辑:

办公室发生的事故确实是驾驶员的错。缺少初始化,并且完全未经测试的TIOCMIWAIT代码导致计算机崩溃。

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

如果有人对我的代码版本感兴趣,请给我发送消息,我会把它发送给您。


2
我很想看看您的代码。您可以将其贡献回tty0tty项目吗?但是,我希望看到人们在Linux内核中改进伪终端代码。例如,添加硬件握手支持和TIOCMIWAIT。
Craig McQueen 2013年

3
“如果有人对我的代码版本感兴趣,请给我发送消息,我会把它发送给您。” 是的,我很感兴趣!您可以在某个地方(例如在GitHub上)指向它吗?
Craig McQueen

7
我将驱动程序上传到:github.com/pitti98/nullmodem对不起,回复花了很长时间。我对stackoverflow不太活跃,却忽略了您的评论!
Peter Remmers

不,我写它是因为我需要它,一旦它足够好以至于可以做我想做的事就停下来。现在它是公开的,我希望它对其他人有用,也许有人在我离开的地方捡起它。
彼得·雷默斯 Peter Remmers)2013年

8

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

还有其他商业选择,例如http://www.ttyredirector.com/

在开放源代码中,Remserial(GPL)也可以使用Unix PTY来完成您想要的操作。它以“原始形式”将串行数据传输到网络套接字。创建端口时必须完成类似于STTY的终端参数设置,以后似乎不支持按RFC 2217中所述进行更改。您应该能够运行两个remserial实例来创建一个像com0com这样的虚拟nullmodem,除了您需要预先设置端口速度等。

Socat(也称为 GPL)就像Remserial的扩展变体一样,具有许多其他选项,包括用于将PTY重定向到其他东西的“ PTY”方法,这可以是Socat的另一个实例。对于单元tets,socat可能比remserial好,因为您可以直接将文件分类到PTY中。请参见联机帮助页上的PTY示例。“ contrib”下存在一个修补程序,以提供RFC2217支持以协商串行线路设置。


6

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

该代码很容易解释。首先,通过运行./main master创建master进程,它将打印到设备正在使用的stderr。之后,您调用./main从设备,其中device是第一个命令中打印的设备。

就是这样。您在这两个过程之间有双向链接。

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

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


1
while(read(fd,&inputbyte,1)== 1){...}在您的代码中未定义。写入未定义。关闭未定义。
Mattis Asp '18

4

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


4

我可以想到三种选择:

实施RFC 2217

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

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

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

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

修改linux串口驱动

另外,Linux的串行端口驱动程序源也很容易获得。以这种方式,保留硬件控制部件,并让一个驱动程序运行两个/ dev / ttySx端口,作为简单的环回。然后将您的真实程序连接到ttyS2,将模拟器连接到另一个ttySx。

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

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

-亚当


1
实际上,空调制解调器USB UART电缆对我来说似乎是一个非常优雅的解决方案,因为它既支持本地测试(如果端口不足,也可以使用USB集线器)和远程调试。
Maxthon Chan

我尚未审查其质量,但是ttynvt通过Linux FUSE实现RFC 2217
Daniel Santos
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.