linux虚拟串口及远程访问

2023-06-07,,

<!--
@page { margin: 0.79in }
h3 { margin-top: 0.18in; margin-bottom: 0.18in; direction: ltr; color: #000000; line-height: 173%; text-align: justify; page-break-inside: avoid; widows: 0; orphans: 0 }
h3.western { font-family: "等线", serif; font-size: 16pt }
h3.cjk { font-family: "Droid Sans Fallback"; font-size: 16pt }
h3.ctl { font-family: ; font-size: 16pt }
h2 { margin-top: 0.18in; margin-bottom: 0.18in; direction: ltr; line-height: 173%; text-align: justify; page-break-inside: avoid; widows: 0; orphans: 0 }
h2.western { font-family: "等线 Light", serif; font-size: 16pt }
h2.cjk { font-family: "Droid Sans Fallback"; font-size: 16pt }
h2.ctl { font-family: ; font-size: 16pt }
p { margin-bottom: 0.1in; direction: ltr; line-height: 120%; text-align: justify; widows: 0; orphans: 0 }
a:link { color: #0000ff; so-language: zxx }
-->

1. 虚拟终端概念

linux中有很多终端,如下简单介绍下各种终端或串口的概念。

1.1 tty:终端设备的统称

tty是Teletype或TeletypeWriter的缩写,中文翻译为电传打字机。电传打字机通常有键盘、收发报器和印字机等组成,是传真机使用以前的通信设备,原理近似电报。后被显示器和键盘所取代,所以现在叫终端比较合适。

终端是一种字符型设备,他有多种类型,通常使用tty来简称各种类型的终端设备。

目前,tty一般指控制终端(man 4 tty),设备文件是/dev/ttyx,常用的就是linux默认提供的6个命令行终端,可通过Ctrl+Alt+Fn切换图形界面或终端窗口。在Ubuntu命令行输入tty显示终端:

$ tty
/dev/tty2

1.2 pty:虚拟终端

A pseudoterminal缩写为pty,是虚拟终端或伪终端,可以在终端模拟器(terminal emulator)中运行,man pty查看。pty是成对的逻辑终端设备(即master和slave设备,对master的操作会反映到slave上,对slave的操作也会反映到master上),与实际物理设备无关。A pty is a pair of virtual character devices that provide a bidirectional communication channel. one end is called master; the other end is called the slave.

linux提供了两套虚拟终端接口,BSD-style和System V-style,System V-style终端也被称为UNIX 98 pseudoterminals,是目前使用的伪终端样式。

An unused UNIX 98 pseudoterminal master is opened by calling posix_openpt(3). (This function opens the master clone device, /dev/ptmx; see pts(4).) After performing any program-specific initializations, changing the ownership and permissions of the slave device using grantpt(3), and unlocking the slave using unlockpt(3)), the corresponding slave device can be opened by passing the name returned by ptsname(3) in a call to open(2).

PTM指pseudoterminal master,PTS指pseudoterminal slave。

/dev/ptmx (UNIX 98 master clone device),所有主设备对应的设备文件都指向/dev/ptmx

/dev/pts/* (UNIX 98 slave devices)

ssh或Telnet登录远程主机时的终端就是pty,运行tty查看:

$ tty
/dev/pts/

伪终端是一对虚拟的字符设备,linux内核使用一种符合tty线规程(line discipline)的双向管道连接伪终端的主从设备。主设备上的任何写入操作都会反映到从设备上,反之亦然。从设备上的应用进程可以像使用传统终端一样读取来自主设备上应用程序的输入,以及向主设备应用输出信息。伪终端从设备应用通常是主设备应用的子进程,主应用打开一对伪终端并fork一个子进程,然后子进程打开并使用从设备。

1.3 串行端口终端

与计算机串行端口(RS-232)连接的终端设备,对应的设备文件名称为/dev/tty+类型+设备编号,如/dev/ttyS0,S表示设备类型,0为指定类型下的设备编号。这里的串行端口可以是通过硬件或软件模拟的,如USB转串口,虚拟串口。

2. 多个虚拟终端

Unix 98伪终端使用流程如下:

使用posix_openpt打开master;
使用grantpt设置调用进程为slave的属主并允许其对slave进行读写操作;
使用unlockpt对slave解锁;
使用ptsname返回slave的设备名;
使用open打开slave设备并进行读写操作。

上述函数都来自glibc库。伪终端编程更常用的API是openpty,直接实现了上述流程的所有步骤。login_tty函数用于实现在指定的终端上启动登录会话。forkpty函数整合了openpty、fork和 login_tty,在网络服务程序可用于为新登录用户打开一对伪终端,并创建相应的会话子进程。

注意:使用opentty,login_pty和forkpty需要链接util库。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pty.h>
#include <utmp.h>
#include <errno.h> #define SLAVE_DEV_NAME_MAX_LEN 128
#define PTY_BUFF_MAX_LEN 1024 int main(int argc, char *argv[])
{
int mpty = , spty = ;
int rv = , n = ;
char spty_name[SLAVE_DEV_NAME_MAX_LEN]={};
char buf[PTY_BUFF_MAX_LEN] = {}; fd_set rfds; rv = openpty(&mpty, &spty, spty_name, NULL, NULL);
if(- == rv){
perror("Failed to get a pty");
return -;
} printf("Get a pty pair, FD -- master[%d], slave[%d]\n", mpty, spty);
printf("Slave name is %s\n", spty_name); FD_ZERO(&rfds);
FD_SET(mpty, &rfds); while(){
rv = select(mpty+, &rfds, NULL, NULL, NULL);
if(rv < ){
perror("Failed to select");
return -;
} if(FD_ISSET(mpty, &rfds)){
n = read(mpty, buf, PTY_BUFF_MAX_LEN);
if(n > ){
// memset(buf+n, 0, PTY_BUFF_MAX_LEN-n);
printf("recv [%d] bytes:[%s]\n", n, buf);
} else if (n == ){
printf("Slave closed\n");
break;
} else {
if(errno == EINTR){
continue;
}
perror("Failed to read the master\n");
return -;
}
}
} close(mpty);
close(spty);
return ;
}

<!--
@page { margin: 0.79in }
p { margin-bottom: 0.1in; direction: ltr; line-height: 120%; text-align: justify; widows: 0; orphans: 0 }
a:link { color: #0000ff; so-language: zxx }
-->

编译及运行:

gcc pty_test.c -o pty_test -lutil -Wall
$ ./pty_test
Get a pty pair, FD -- master[], slave[]
Slave name is /dev/pts/
recv [] bytes:[]
recv [] bytes:[hello world]

另一终端:

$ echo -n "" > /dev/pts/
$ echo -n "hello world" > /dev/pts/

每次运行上述程序,生成一个虚拟终端口(slave),由此同一主机可运行多个虚拟终端口(slave)。可通过文件/proc/sys/kernel/pty/max查询或修改伪终端数量。

$ cat /proc/sys/kernel/pty/max

3. 远程访问串口

通过网络远程访问串口,首先需要把串口虚拟化网络端口,之后在网络中的另外一个主机上通过Telnet等工具直接访问该网络端口,或者把网络端口逆向为一个虚拟串口,进而通过minicom等工具进行访问。

socat工具可以实现上述功能。如本地(虚拟串口)/dev/pts6,主机IP:192.168.134.144,主机端口54321,对端主机虚拟串口文件tty.virt001,可通过如下步骤测试。

主机1串口转TCP端口:

sudo socat tcp-l:54321,reuseaddr,fork file:/dev/pts/6,waitlock=/var/run/ttypts.lock,clocal=1,cs8,nonblock=1,ixoff=0,ixon=0,ispeed=9600,ospeed=9600,raw,echo=0,crtscts=0

主机2TCP端口转虚拟串口:

sudo socat pty,link=/dev/tty.virt001 tcp:192.168.134.144:54321

主机2远程访问串口:

sudo minicom -D /dev/tty.virt001

telnet 192.168.134.144 54321

aaarticlea/png;base64,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" alt="" name="图片 1" width="398" height="283" align="bottom" border="0" />

4. 虚拟终端双向收发

上述程序测试示例中由于ptm与pts在一个程序中,没有控制ptm的发送,不便于测试观察,网上有程序实现用两组虚拟终端中两个slave配对,从而基于串口的双向数据收发。

#!/usr/bin/env python3
#--coding = utf-8 -- import pty
import os
import select def mkpty():
master1, slave = pty.openpty()
slaveName1 = os.ttyname(slave)
master2, slave = pty.openpty()
slaveName2 = os.ttyname(slave)
print ('\nslave device names: ', slaveName1, slaveName2)
return master1, master2 if __name__ == "__main__":
master1, master2 = mkpty()
while True:
rl, wl, el = select.select([master1, master2], [], [], 1)
for master in rl:
data = os.read(master, 128)
print ("read %d data:" %len(data))
if master == master1:
os.write(master2, data)
else :
os.write(master1, data)

<!--
@page { margin: 0.79in }
p { margin-bottom: 0.1in; direction: ltr; line-height: 120%; text-align: justify; widows: 0; orphans: 0 }
a:link { color: #0000ff; so-language: zxx }
-->

上述程序用python实现了两个虚拟终端slave双向收发。

两个主机都可通过minicom双向收发数据。

测试中唯一不足是接收端对换行不能正确处理,可以回车但不能换行,可能与minicom设置有关,编程处理应该无问题。

此外注意到python程序是一个一个字符处理的,并没有按照换行符整行发送,不能正确换行可能也与python程序有关。

5. 常见的虚拟串口问题

1. linux下如何生成虚拟串口?

linux中有虚拟终端的概念即pty,pty是成对的逻辑终端设备(有两个终端组成,支持双向收发),linux系统调用原生支持生成虚拟终端。

无论是实体串口,还是虚拟串口,表现形式都是串口,在linux下都是通过termios访问设置的。Ubuntu下cutecom图形界面串口调试工具可以生成并测试虚拟串口。

windows下vspd软件(Virtual Serial Port Driver)可以生成并测试虚拟串口。

2. 串口的远程访问?

实体串口或虚拟串口(虚拟终端)要想实现远程访问,需要将串口数据转换到网络端口,远程通过网络实现远程访问串口。常用的工具ncat、socat都可以实现此功能。

3. 3G或4G无线模块怎样实现的多串口访问?

测试3G或4G模块时看到模块虚拟出多个串口,这是如何实现的呢?这些串口本身就是在模块内部的虚拟串口,通过USB载体表现出来。

此和上述的网络访问虚拟串口不同,这里的虚拟串口的访问借助USB协议,要求模块实现USB协议来表征模块本身实现的接口(多个虚拟串口)。

当主机访问3G或4G模块时,通过USB总线枚举来找到模块实现的串口功能;而3G或4G模块内部,多串口可能是虚拟串口,也可能是实体串口(芯片),但需要实现USB协议。

参考:

    Linux终端简介与pty编程
    串口虚拟化:通过网络访问串口
    Linux下的虚拟终端(可用于在本机上模拟串口进行调试)
    Ubuntu 下使用虚拟串口进行开发测试
    linux下串口转TCP/IP的终端服务器实现  通过nc实现

<!--
@page { margin: 0.79in }
h2 { margin-top: 0.18in; margin-bottom: 0.18in; direction: ltr; line-height: 173%; text-align: justify; page-break-inside: avoid; widows: 0; orphans: 0 }
h2.western { font-family: "等线 Light", serif; font-size: 16pt }
h2.cjk { font-family: "Droid Sans Fallback"; font-size: 16pt }
h2.ctl { font-family: ; font-size: 16pt }
p { margin-bottom: 0.1in; direction: ltr; line-height: 120%; text-align: justify; widows: 0; orphans: 0 }
a:link { color: #0000ff; so-language: zxx }
-->
<!--
@page { margin: 0.79in }
p { margin-bottom: 0.1in; direction: ltr; line-height: 120%; text-align: justify; widows: 0; orphans: 0 }
a:link { color: #0000ff; so-language: zxx }
-->
<!--
@page { margin: 0.79in }
p { margin-bottom: 0.1in; direction: ltr; line-height: 120%; text-align: justify; widows: 0; orphans: 0 }
a:link { color: #0000ff; so-language: zxx }
-->

linux虚拟串口及远程访问的相关教程结束。

《linux虚拟串口及远程访问.doc》

下载本文的Word格式文档,以方便收藏与打印。