Linux串口转远程串口,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/11
偽終端是一對虛擬的字符設備,linux內核使用一種符合tty線規程(line discipline)的雙向管道連接偽終端的主從設備。主設備上的任何寫入操作都會反映到從設備上,反之亦然。從設備上的應用進程可以像使用傳統終端一樣讀取來自主設備上應用程序的輸入,以及向主設備應用輸出信息。偽終端從設備應用通常是主設備應用的子進程,主應用打開一對偽終端并fork一個子進程,然后子進程打開并使用從設備。
1.3 串行端口終端
與計算機串行端口(RS-232)連接的終端設備,對應的設備文件名稱為/dev/tty+類型+設備編號,如/dev/ttyS0,S表示設備類型,0為指定類型下的設備編號。這里的串行端口可以是通過硬件或軟件模擬的,如USB轉串口,虛擬串口。
2. 多個虛擬終端
Unix 98偽終端使用流程如下:
1.使用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 #include#include#include#include#include
#define SLAVE_DEV_NAME_MAX_LEN 128
#define PTY_BUFF_MAX_LEN 1024
int 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
遠程訪問串口
通過網絡遠程訪問串口,首先需要把串口虛擬化網絡端口,之后在網絡中的另外一個主機上通過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,waitslave tcp:192.168.134.144:54321
主機2遠程訪問串口:
sudo minicom -D /dev/tty.virt001
或
telnet 192.168.134.144 54321
虛擬終端雙向收發
上述程序測試示例中由于ptm與pts在一個程序中,沒有控制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雙向收發。
參考:
總結
以上是生活随笔為你收集整理的Linux串口转远程串口,linux虚拟串口及远程访问的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 修改linux系统iqn,linux i
- 下一篇: linux下软件如何防破裂,linux下