Linux下的虚假串行通信

时间:2010-03-23 13:55:58

标签: python linux serial-port

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

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

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模块,但也无法使用它。我可以从pty.openpty()获取主文件描述符和从属文件描述符,但尝试读取或写入它们只会导致IOError Bad File Descriptor错误消息。

更新

评论向我指出了使用socat设置虚拟串行连接的SO问题Are there some program like COM0COM in linux?。 我这样用过:

socat PTY,link=$HOME/COM1 PTY,link=$HOME/COM2

对于其他人,谢谢你给我提供有价值的信息。 我选择接受 Vinay Sajips 的答案,因为这是我在提出socat建议之前所采用的解决方案。它似乎运作良好。

3 个答案:

答案 0 :(得分:9)

最好使用pyserial与串口通信,你可以创建实现serial.Serialread的{​​{1}}类的模拟版本, readline以及您需要的任何其他方法。

答案 1 :(得分: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。

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

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