Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Linux下的伪串行通信_Python_Linux_Serial Port - Fatal编程技术网

Python Linux下的伪串行通信

Python Linux下的伪串行通信,python,linux,serial-port,Python,Linux,Serial Port,我有一个应用程序,我想模拟设备和“调制解调器”之间的连接。该设备将连接到串行端口,并通过该端口与软件调制解调器通信 出于测试目的,我希望能够使用模拟软件设备来测试发送和接收数据 Python代码示例 device = Device() modem = Modem() device.connect(modem) device.write("Hello") modem_reply = device.read() 现在,在我的最后一个应用程序中,我将只通过/dev/ttyS1或COM1或应用程序

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

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

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\u-fake\u-serial\u-port
并对其进行读写

我还使用了
pty
模块,但也无法使其正常工作。我可以从
pty.openpty()
获取主文件描述符和从文件描述符,但尝试读取或写入它们只会导致
IOError错误文件描述符
错误消息

更新 评论将我引向SO问题,该问题使用
socat
设置虚拟串行连接。 我是这样用的:

#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;
}
socat PTY,link=$HOME/COM1 PTY,link=$HOME/COM2

其他人,谢谢你们给我提供了宝贵的信息。
我选择接受Vinay Sajips的回答,因为这是我在socat建议出现之前所寻求的解决方案。它似乎工作得很好。

可能最好使用它与串行端口通信,您只需创建一个模拟版本的
串行.serial
类,它实现了
读取
读取线
写入
以及您需要的任何其他方法。

您使用伪终端的方法是正确的。要做到这一点,您的模拟软件设备需要首先打开一个伪终端主机-这是它将读取和写入的文件描述符,当它与您正在测试的串行软件通信时。然后,它需要授予对伪终端从设备的访问权限并解锁,并获取从设备的名称。然后,它应该在某个地方打印出从设备的名称,以便您可以告诉其他软件将其作为串行端口打开(即,该软件将打开一个类似
/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;
}
定义源代码
#包括
#包括
#包括
int main(int argc,char*argv[])
{
int-pt;
pt=打开(“/dev/ptmx”,O_RDWR | O_NOCTTY);
if(pt<0)
{
perror(“open/dev/ptmx”);
返回1;
}
格兰特普特(pt);
解锁(pt);
fprintf(stderr,“从设备:%s\n”,ptsname(pt));
/*现在开始假装是调制解调器,读写“pt”*/
/* ... */
返回0;
}

希望这很容易转换成Python。

以下是pts模拟(caf)串行通信的Python版本:

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()
与模拟串行相比,它有一些优点,即使用串行代码和一些串行端口人工制品

如果您想测试串行端口的打开,可以交换主端口和从端口,并使用
os.ttyname(salve\u fd)
作为串行端口名。但我不能保证交换主从的副作用。最值得注意的是,您可以关闭和重新打开奴隶,但您关闭主奴隶也会死亡


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

您是否尝试过类似PTY模块的方法?mtrw:谢谢!成功了!检查一下这个谢谢,这就是我最后要做的。