linux虚拟串口及远程访问
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 ;
}
编译及运行:
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
主机2将TCP端口转虚拟串口:
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)
上述程序用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实现
linux虚拟串口及远程访问的更多相关文章
- Linux 虚拟串口及 Qt 串口通信实例
Linux 虚拟串口及 Qt 串口通信实例 2011-06-22 17:49 佚名 互联网 字号:T | T Linux 虚拟串口及 Qt 串口通信实例是本文所要介绍的内容,在实现过程中,打开了两个伪 ...
- Linux虚拟串口
将下列Python代码保存成VitrualCom.py: Code#! /usr/bin/env python #coding=utf-8 import pty import os import se ...
- Windows驱动——虚拟机 虚拟串口 双机调试
=================================版权声明================================= 版权声明:原创文章 谢绝转载 请通过右侧公告中的“联系邮 ...
- 上位机用USB做虚拟串口,总算抓到一个纯代码的总结了,没有坑的完美解决。
用libUSB来实现自己的驱动+下位机理论速度.=1M字节每秒. 达到极限速度 WINDOWS已经自带虚拟串口驱动,只不过还需要一个Inf文件 方法1:直接下载一个串口inf,来修改文件. 方 ...
- VSPM虚拟串口使用
(1)打开虚拟串口工具,当你设置好你程序中的串口信息后,打开程序中的串口,然后虚拟串口中所显示的就是程序的所提供的串口信息 (2)选中其中一个串口,修改管理信息,点击”重新连接“ , 直接在管理那里, ...
- Go 语言开发的基于 Linux 虚拟服务器的负载平衡平台 Seesaw
负载均衡系统 Seesaw Seesaw是由我们网络可靠性工程师用 Go 语言开发的基于 Linux 虚拟服务器的负载平衡平台,就像所有好的项目一样,这个项目也是为了解决实际问题而产生的. Seesa ...
- linux 使用串口连接设备console
linux使用串口连接cisco设备的console linux 自带一个串口命令:minicom,需要经过设置,之后就可以连接了. 传说是默认就可以,我可能RP不好,我必须要经过设置才可以. ...
- linux下串口的阻塞和非阻塞操作
有两个可以进行控制串口阻塞性(同时控制read和write):一个是在打开串口的时候,open函数是否带O_NDELAY:第二个是可以在打开串口之后通过fcntl()函数进行控制. 阻塞的定义: 对于 ...
- Linux下串口编程入门
简介: Linux操作系统从一开始就对串行口提供了很好的支持,本文就Linux下的串行口通讯编程进行简单的介绍. 串口简介 串行口是计算机一种常用的接口,具有连接线少,通讯简单,得到广泛的使用.常用 ...
随机推荐
- fatal error: sys/videoio.h: No such file or directory
Determining if the include file sys/videoio.h exists failed with the following output:Change Dir: /h ...
- 解决catalina.out文件过大的问题
有用Tomcat的人,绝对都会遇到这样一个问题:catalina.out文件过大. 它是Tomcat默认生成的日志文件,会随着时间的推移,逐渐增大,不断的增长,甚至达到几G,几十G的大小.由于文件过大 ...
- if [ $? -eq 0 ]的含义
if [ $? -eq 0 ]语句代表上一个命令执行后的退出状态 $0: shell或shell脚本的名字$*: 以一对双引号给出参数列表$@: 将各个参数分别加双引号返回$#: 参数 ...
- xml 3 字节的 UTF-8 序列的字节 3 无效
今天在eclipse中编写**.xml文件时,注释中的中文被eclipse识别到错误:3 字节的 UTF-8 序列的字节 3 无效,曾多次遇到该问题,问题的根源是: The cause of this ...
- 导出excel按照指定格式
1.项目有个需求,要按照特定格式 导出Excel表格. 正常的都是一行 ,下面是数据.这次有个变动,就是每隔 几列要换行,下面是数据.在下面是数据部分.花了一上午写了下需求,不难但是花时间 //实现特 ...
- 新手學python之新體驗
1. 使用縮進方式做為程式塊開始結束的標示,程式換行在行末尾加 "\" 2. 元祖(Tuple)數據類型,和List的不同是Tuple不能修改,優點是執行速度比List快,因為不能 ...
- Postgres-XL集群ERROR :Failed to get pooled connections原因说明
集群说明 6台服务器.其中1台(rt67-1)运行GTM,其余5台均运行1个GTM_PROXY.1个Coordinator node.3个Data node.每个服务器连接到3组网络中,每个Data ...
- windows SDK中的wininet写http客户端
BOOL InternetSetOption( _In_ HINTERNET hInternet, _In_ DWORD dwOption, _In_ LPVOID lpBuffer, _In_ ...
- 虚拟机出现“The system is running in low-graphics mode”的解决方法
我用虚拟机安装了ubuntu的版本后,又在上面安装了几个插件,第二次打开虚拟机就出现下面的提示: 通过在网上查找教程,找到了以下的解决方法 1.Ctrl+Alt+F1进入控制台 2.输入用户密码 3. ...
- java之spring之对象的创建
首先提供目录结构如下: 下面提供各文件代码,以供参考: UserDynamicFactory.java package cn.sxt.factory; import cn.sxt.vo.User; / ...