用于两个进程之间通信的伪终端

用于两个进程之间通信的伪终端

我正在编写一个使用第三方 C 库的可执行文件(libmodbus如果重要的话)通过串行设备进行通信(在我的例子中,/dev/ttyUSB0或者类似于通过基于 FTDI 芯片组的 USB 到 RS485 适配器进行 RS-485 通信)。这个基于 CLI 参数的可执行文件可以启动命令(在我的例子中,就像 modbus 客户端一样)然后等待响应(在我的例子中,来自外部 modbus 服务器),或者监听传入的命令(在我的例子中,就像modbus 服务器)然后生成响应。

我想自动测试我的可执行文件,而不需要某些外部设备。换句话说,我想启动可执行文件的两个实例,其中:

  • 第一个实例进入 modbus 客户端模式并用于/dev/xxxx通信
  • 第二个实例置于 modbus 服务器模式并用于/dev/yyyy通信
  • 设置/dev/xxxx/dev/yyyy都充当串行设备,本质上是同一根电线的两端。

从我读到的内容来看pty 联机帮助页,我相信/dev/xxxx/dev/yyyy是伪终端的两端。这让我想到了我的问题:

  1. 手册页引用了 BSD 风格的伪终端,这似乎更适合我想要做的事情。
    • 我对 BSD 风格的伪终端的理解正确吗?
    • 如果是这样,是否可以在非 BSD Linux 发行版上创建 BSD 风格的伪终端?具体来说,我使用的是 debian 10、11、12(以及基于 debian 的版本,例如 Ubuntu 20.04、22.04)
  2. 该手册页还引用了 UNIX 98 伪终端,它们是使用posix_openpt().然而,即使在后续的grantpt()and之后,我也只能为 pty 的客户端提供 unlockpt()一个设备,而主端只是可执行文件内的一个文件描述符。/dev/pts
    • 我的理解是(松散地基于像这样的代码) 正确的?
    • 如果是这样,我可以使用什么技巧将主端文件描述符转换为正确的,/dev/xxxx这是唯一可用的 API获取 modbus 上下文
  3. 是否还有其他“标准”Linux 工具可以完成我想要做的事情?看起来像这样的工具这里提到的那些期望将可执行文件的 STDIO 连接到 pty。

答案1

您可以使用以下命令设置 PTY“虚拟串行端口”socat

socat \
  pty,rawer,echo=0,link=/tmp/portA \
  pty,rawer,echo=0,link=/tmp/portB

这将创建两个 PTY 设备和两个到这些设备的符号链接。在我的系统上,上面的命令创建了:

$ ls -l /tmp/port*
lrwxrwxrwx 1 lars lars 11 Jul 24 11:49 /tmp/portA -> /dev/pts/20
lrwxrwxrwx 1 lars lars 11 Jul 24 11:49 /tmp/portB -> /dev/pts/21

您可以将这些 pty 设备视为串行端口。例如,我可以连接slcand到这些设备来创建 CANbus 接口:

slcand -o -c -f -s6 $(readlink /tmp/portA)
slcand -o -c -f -s6 $(readlink /tmp/portB)

或者我可以连接picocom到每个端口并通过虚拟链接聊天。在一个窗口中:

picocom $(readlink /tmp/portA)

在另一个窗口中:

picocom $(readlink /tmp/portB)

ETC。


UNIX-98 pty 和 BSD 样式 pty 的行为相同;区别在于它们的分配方式(UNIX-98 pty 是动态分配的,而 BSD 样式 pty 是预分配设备)。

然而,即使在随后的 grantpt() 和 unlockpt() 之后,我只能为 pty 的客户端提供一个 /dev/pts 设备,而主端只是可执行文件内的一个文件描述符。

这是正确的;要链接两个 pty 以创建虚拟串行线,您的代码需要打开两个 pty 设备,然后处理两者之间的数据移动(这就是socat上面示例中所做的操作)。

相关内容