Linux下的虚假串行通信
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux下的虚假串行通信相关的知识,希望对你有一定的参考价值。
我有一个应用程序,我想模拟设备和“调制解调器”之间的连接。设备将连接到串行端口,并通过它与软件调制解调器通信。
出于测试目的,我希望能够使用模拟软件设备来测试发送和接收数据。
示例Python代码
device = Device()
modem = Modem()
device.connect(modem)
device.write("Hello")
modem_reply = device.read()
现在,在我的最终应用程序中,我将只传递/ dev / ttyS1或COM1或其他任何应用程序。但是我怎么能在软件中做到这一点?我正在运行Linux,应用程序是用Python编写的。
我已经尝试制作FIFO(mkfifo ~/my_fifo
)并且确实有效,但是我需要一个FIFO用于写入,一个用于读取。我想要的是打开~/my_fake_serial_port
并读取和写入。
我也用pty
module付了钱,但也无法让它工作。我可以从pty.openpty()
获取主文件和从属文件描述符,但尝试读取或写入它们只会导致IOError Bad File Descriptor
错误消息。
更新
评论向我指出了使用Are there some program like COM0COM in linux?设置虚拟串行连接的SO问题socat
。我用它是这样的:
socat PTY,link=$HOME/COM1 PTY,link=$HOME/COM2
对于其他人,感谢您给我有价值的信息。我选择接受Vinay Sajips的答案,因为这是我在提出socat建议之前所采用的解决方案。它似乎工作得很好。
最好使用pyserial与串口通信,你可以创建一个serial.Serial
类的模拟版本,它实现了read
,readline
,write
以及你需要的任何其他方法。
你在伪终端的正确轨道上。要做到这一点,你的模拟软件设备需要首先打开一个伪终端主机 - 当它正在与您正在测试的串行软件通信时,它将读取和写入的文件描述符。然后,它需要授予访问和解锁伪终端从属的权限,并获取从属设备的名称。然后它应该在某处打印出从设备的名称,这样你就可以告诉其他软件打开它的串口(即该软件将打开像/dev/pts/0
而不是/dev/ttyS1
这样的名字)。
然后,模拟器软件只从伪终端的主端读取和写入。在C中,它看起来像这样:
#define _XOPEN_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
int pt;
pt = open("/dev/ptmx", O_RDWR | O_NOCTTY);
if (pt < 0)
{
perror("open /dev/ptmx");
return 1;
}
grantpt(pt);
unlockpt(pt);
fprintf(stderr, "Slave device: %s
", ptsname(pt));
/* Now start pretending to be a modem, reading and writing "pt" */
/* ... */
return 0;
}
希望这很容易转换为Python。
这是pts-emulated(caf's)串行通信的pythonic版本:
from serial import Serial
driver = MyDriver() # what I want to test
peer = serial.Serial()
driver.port.fd, peer.fd = posix.openpty()
driver.port._reconfigurePort()
peer.setTimeout(timeout=0.1)
peer._reconfigurePort()
driver.start()
# peer.write("something")
# driver.get_data_from_serial()
它比模拟Serial有一些优点,即使用串行代码并执行一些串行端口伪像。
如果要测试串口的打开,可以交换主站和从站,并使用os.ttyname(salve_fd)
作为串口名。我不能担保交换主人和奴隶的副作用。最值得注意的是,你可以关闭并重新打开奴隶,但是你也可以关闭主奴隶。
如果您的测试代码在同一个进程中运行,这就像一个魅力。我还没有用多个/单独的过程解决这个问题。
以上是关于Linux下的虚假串行通信的主要内容,如果未能解决你的问题,请参考以下文章