1. 虚拟终端概念

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

1.1 tty:终端设备的统称

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

终端是一种字符型设备,他有多种类型,通常使用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是成对的逻辑终端设备(即masterslave设备,对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-styleSystem V-styleSystem 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).

PTMpseudoterminal masterPTSpseudoterminal slave

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

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

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

$ tty/dev/pts/11

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

1.3 串行端口终端

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

2. 多个虚拟终端

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

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

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

注意:使用openttylogin_ptyforkpty需要链接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        1024int main(int argc, char *argv[])
{int mpty = 0, spty = 0;int rv = 0, n = 0;char spty_name[SLAVE_DEV_NAME_MAX_LEN]={0};char buf[PTY_BUFF_MAX_LEN] = {0};fd_set rfds;rv= openpty(&mpty, &spty, spty_name, NULL, NULL);if(-1 ==rv){perror("Failed to get a pty");return -1;}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(1){rv= select(mpty+1, &rfds, NULL, NULL, NULL);if(rv < 0){perror("Failed to select");return -1;}if(FD_ISSET(mpty, &rfds)){n=read(mpty, buf, PTY_BUFF_MAX_LEN);if(n > 0){//memset(buf+n, 0, PTY_BUFF_MAX_LEN-n);printf("recv [%d] bytes:[%s]\n", n, buf);}else if (n == 0){printf("Slave closed\n");break;}else{if(errno ==EINTR){continue;}perror("Failed to read the master\n");return -1;}}}close(mpty);close(spty);return 0;
}

编译及运行:

gcc pty_test.c -o pty_test -lutil -Wall
$ ./pty_test
Get a pty pair, FD-- master[3], slave[4]
Slave nameis /dev/pts/6recv [1] bytes:[1]
recv [11] bytes:[hello world]

另一终端:

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

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

$ cat /proc/sys/kernel/pty/max4096

3. 远程访问串口

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

socat工具可以实现上述功能。如本地(虚拟串口)/dev/pts6,主机IP192.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

4. 虚拟终端双向收发

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

#!/usr/bin/env python3#--coding = utf-8 --importptyimportosimportselectdefmkpty():master1, slave=pty.openpty()slaveName1=os.ttyname(slave)master2, slave=pty.openpty()slaveName2=os.ttyname(slave)print ('\nslave device names:', slaveName1, slaveName2)returnmaster1, master2if __name__ == "__main__":master1, master2=mkpty()whileTrue:rl, wl, el= select.select([master1, master2], [], [], 1)for master inrl: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协议。

参考:

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

转载于:https://www.cnblogs.com/embedded-linux/p/11318521.html

linux虚拟串口及远程访问相关推荐

  1. Linux串口转远程串口,linux虚拟串口及远程访问

    1. 虚拟终端概念 linux中有很多终端,如下简单介绍下各种终端或串口的概念. 1.1 tty:终端设备的统称 tty是Teletype或TeletypeWriter的缩写,中文翻译为电传打字机.电 ...

  2. linux 控制虚拟串口,linux虚拟串口控制器实现-适用于无开发板学习tty driver-好向圈...

    在前面几章,我们介绍了tty子系统的框架.数据结构.tty驱动的注册与注销等内容,本章我们借助 之前学习的内容开发一个虚拟的串口控制器驱动,以便我们理解开发串口驱动的步骤及驱动开发实践. 本次实现的虚 ...

  3. Linux c语言虚拟串口,利用socat和cutecom实现Linux虚拟串口通信

    (1)打开终端,输入 sudo apt-get install socat 等待socat安装完成- (2)输入 socat -d -d pty,raw,echo=0 pty,raw,echo=0 我 ...

  4. linux虚拟串口创建,linux虚拟串口编程

    环境: unbuntu14 虚拟机,已设置可联网 目的1:在linux环境下读写虚拟串口(2虚拟串口连接) 步骤: 一,创建虚拟串口 1.安装虚拟软件 apt-get install socat 2. ...

  5. c# 蓝牙虚拟串口_C# 虚拟串口通信

    将主端口COM8拆分成 COM1和COM2两个虚拟端口 COM8接收的消息会传递给COM1和COM2 SerialPort spSend;//spSend,spReceive用虚拟串口连接,它们之间可 ...

  6. linux内核配置usb虚拟串口,Linux USB虚拟串口设备

    Linux内核中usb设备侧驱动程序分成3个层次:UDC驱动程序.Gadget API和Gadget驱动程序.UDC驱动程序(USB控制器)直接访问硬件,控制USB设备和主机间的底层通信,向上层提供与 ...

  7. socat 虚拟串口在 linux OS中如何实现?

    socat虚拟串口工具 用途:linux socat 将2个串口通过虚拟的方式连接起来,这样就可以:直接对串口程序进行调试了. 对串口程序进行调试,不再需要外部串口. Win OS Win com0c ...

  8. Linux下的虚拟串口驱动(一)

    欢迎转载,转载请注明出处. 前言 最近准备在Linux下,实现虚拟串口驱动:但因为毕业后,一直从事的是裸机驱动开发,所以Linux下的设备驱动,就慢慢忘记了:为了实现这一功能,在网上也查找了很多资料, ...

  9. Linux下自定义虚拟串口驱动

    前些天给新的板子修改BUG的时候,发现这块板子的串口是接在板载MCU上,我们的主SOC(海思HI3520D)上已经没有多余的串口.于是问题来了- 我们很多的上层应用都是通过串口和传感器通讯的,而且程序 ...

最新文章

  1. Android自定义RulerView
  2. c语言中 字符串常量的界定符,C字符串操作函数
  3. 算法 从 数中选出_算法可以选出胜出的nba幻想选秀吗
  4. 使用 Caddy 替代 Nginx,全站升级 https,配置更加简单
  5. 显卡服务器已停止响应,Win7电脑提示显卡驱动程序已停止响应并且已恢复如何解决?...
  6. spring4.x(4)--SpringIOC的HelloWorld
  7. position属性absolute(绝对定位),relatve(相对定位)
  8. 一个大图切成几个小图加载速度更快_谷歌SEO页面速度的重要性
  9. 现浇板用弹性计算方法_自建房砖混结构现浇楼板配筋的要求和计算方法
  10. 大数据技术成功案例和趋势 2021-25
  11. python爬取京东商品信息_python爬虫:爬取京东商品信息
  12. windows10如何使用Wallpaper Engine实现动态锁屏壁纸?把WE的壁纸应用到锁屏。
  13. 用计算机控制人造卫星和导弹发射,用计算机控制人造卫星和导弹的发射,按计算机应用的分类,它应属于什么...
  14. 计算机专业英语字典aqq,最新的英语qq网名
  15. Shell脚本——免交互
  16. (3)登录界面——登录
  17. 《哪吒》票房破25亿,我用AI分析了它20W+评论数据
  18. 机械振动学习笔记1-3章
  19. 公司现有一个工作组workgroup,需要添加samba服务器作为文件服务器,并发布共享目录
  20. 单片机实验说明<二>外部中断基本使用

热门文章

  1. linux shell 函数 格式化,速查笔记(linux shell编程)
  2. 希沃展台如何使用_展商该如何做好展台设计?
  3. java 注销变量_[ Java学习基础 ] Java对象的创建和销毁
  4. 进阶的Redis之数据持久化RDB与AOF
  5. 《大道至简》阅读笔记
  6. AngularJS scope 学习
  7. linux 设置开机启动
  8. 一步一步教你使用AgileEAS.NET基础类库进行应用开发-基础篇-演示ORM中的查询
  9. windows mobile 开发 web service 未能建立与网络的连接、无法连接到远程服务器
  10. pythonfor久久_python 九九乘法表 for循环