Linux下的虚假串行通信

问题描述 投票:15回答:3

我有一个应用程序,我想模拟设备和“调制解调器”之间的连接。设备将连接到串行端口,并通过它与软件调制解调器通信。

出于测试目的,我希望能够使用模拟软件设备来测试发送和接收数据。

示例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并读取和写入。

我也用ptymodule付了钱,但也无法让它工作。我可以从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建议之前所采用的解决方案。它似乎工作得很好。

python linux serial-port
3个回答
9
投票

最好使用pyserial与串口通信,你可以创建一个serial.Serial类的模拟版本,它实现了readreadlinewrite以及你需要的任何其他方法。


5
投票

你在伪终端的正确轨道上。要做到这一点,你的模拟软件设备需要首先打开一个伪终端主机 - 当它正在与您正在测试的串行软件通信时,它将读取和写入的文件描述符。然后,它需要授予访问和解锁伪终端从属的权限,并获取从属设备的名称。然后它应该在某处打印出从设备的名称,这样你就可以告诉其他软件打开它的串口(即该软件将打开像/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\n", ptsname(pt));

    /* Now start pretending to be a modem, reading and writing "pt" */
    /* ... */
    return 0;
}

希望这很容易转换为Python。


1
投票

这是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)作为串口名。我不能担保交换主人和奴隶的副作用。最值得注意的是,你可以关闭并重新打开奴隶,但是你也可以关闭主奴隶。

如果您的测试代码在同一个进程中运行,这就像一个魅力。我还没有用多个/单独的过程解决这个问题。

© www.soinside.com 2019 - 2024. All rights reserved.