tty是控制终端设备文件的统称,代表正控制着系统的终端
由pty master和pty slave构成;图形终端和远程控制终端都是pty
主机的显示器称为控制台终端console,当在控制台终端登录时,tty1是虚拟终端,使用ALT+F(1-6)来切换虚拟终端tty[1~6],tty0是代表当前所使用的虚拟终端的别名
1、串口终端、控制台终端、伪终端都可以称为控制终端
2、串口终端:标准输入输出都是指向串口,而非控制台屏幕
3、伪终端:用secure CRT或putty等软件的telnet/ssh按照协议发送指令内容,由linux telnetd或sshd服务调用mingetty完成标准输入输出设备的对接,并完成login。
串口
用户常见的数据通信的基本方式有两种:
串行通信是计算机常用的接口,如:RS-232-C接口。该标准规定采用一个DB25芯引脚连接器或DB9芯引脚连接器
异步串行通信
发送一个逻辑”0”,表示字符资料传送开始
可允许4,5,6,7的数据位
一个字符资料结束的标志位,支持1/1.5/2位的停止位
根据传送数据内’1’的个数是偶数还是奇数来校验数据是否传送准确
在没有资料发送时,线路处于逻辑“1”状态
串口配置流程
设置波特率
struct termios newtio,oldtio;
tcgetattr( fd,&oldtio);
newtio.c_cflag | = CLOCAL | CREAD;
cfsetispeed(&newtio, B115200);
cfsetospeed(&newtio, B115200);
newtio.c_cflag &= ~CSIZE;
newtio.c_cflag |= CS8;
newtio.c_cflag |= PARENB;
newtio.c_cflag |= PARODD;
newtio.c_iflag |= (INPCK | ISTRIP);
newtio.c_iflag |= (INPCK | ISTRIP);
newtio.c_cflag |= PARENB;
newtio.c_cflag &= ~PARODD;
newtio.c_cflag &= ~CSTOPB;
newtio.c_cc[VTIME] = 0;
newtio.c_cc[VMIN] = 0;
设置流控制
newtio.c_cflag &= ~CRTSCTS
newtio.c_cflag |= CRTSCTS
newtio.c_cflag | = IXON|IXOFF|IXANY
设置串口堵塞模式
fcntl(fd, F_SETFL, 0);
fcntl (fd, F_SETFL, FNDELAY);
//*****************************************设置串口参数*******************************************
//2013.10.15.
//函数名:void set_opt(int fd, int nBit, int nECC)
//参数:int fd[文件描述符];int nBit[数据位长度7或8];int nECC[奇偶校验1奇校验、2偶校验、0没有]
//参数:int nSpeed[波特率];int nStop[停止位1或2]
//*****************************************设置串口参数*************************************
#include
#include
#include
#include
#include
#include
#include
#include
#include
int set_opt(int fd, int nBit, int nECC, int nSpeed, int nStop, bool Block)
{
struct termios newstr;
struct termios oldstr;
memset(&newstr, 0, sizeof(newstr));
memset(&oldstr, 0, sizeof(oldstr));
//把原来的参数保存到oldterm
tcgetattr(fd, &oldstr);
//设置字符控制
newstr.c_cflag |= (CLOCAL | CREAD); //CLOCAL:忽略调制解调器线路状态。CREAD:使用接收器
newstr.c_cflag &= ~CSIZE;
switch(nBit)
{
case 7:
newstr.c_cflag |= CS7; //设置字符长度为7
break;
case 8:
newstr.c_cflag |= CS8; //设置字符长度为8
break;
}
//设置校验位
switch(nECC)
{
case 0: //无校验
newstr.c_cflag &= ~PARENB;
break;
case 1: //设置奇校验
newstr.c_cflag |= PARENB;
newstr.c_cflag |= PARODD;
newstr.c_iflag |= (INPCK | ISTRIP);
break;
case 2: //设置偶校验
newstr.c_iflag |= (INPCK | ISTRIP);
newstr.c_cflag |= PARENB;
newstr.c_cflag &= ~PARODD;
break;
}
//设置波特率
switch(nSpeed)
{
case 2400:
cfsetispeed(&newstr,B2400);
cfsetospeed(&newstr,B2400);
break;
case 4800:
cfsetispeed(&newstr,B4800);
cfsetospeed(&newstr,B4800);
break;
case 9600:
cfsetispeed(&newstr,B9600);
cfsetospeed(&newstr,B9600);
break;
case 57600:
cfsetispeed(&newstr,B57600);
cfsetospeed(&newstr,B57600);
break;
case 115200:
cfsetispeed(&newstr,B115200);
cfsetospeed(&newstr,B115200);
break;
case 460800:
cfsetispeed(&newstr,B460800);
cfsetospeed(&newstr,B460800);
break;
default:
cfsetispeed(&newstr,B9600);
cfsetospeed(&newstr,B9600);
break;
}
//设置停止位
switch(nStop)
{
case 1:
newstr.c_cflag &= ~CSTOPB; //设置停止位为1
break;
case 2:
newstr.c_cflag |= CSTOPB; //设置停止位为2
break;
}
//设置阻塞时间(阻塞条件下有效)
newstr.c_cc[VTIME] = 150; //(阻塞时间15s)
newstr.c_cc[VMIN] = 0;
if (Block)
{
fcntl(fd, F_SETFL, 0); //设置堵塞
}
tcflush(fd, TCIFLUSH); //清空
int i = tcsetattr(fd, TCSAFLUSH, &newstr);
if (i != 0)
{
perror("Com Set Error");
return 1;
}
printf("Com Set Success!");
return 0;
}
int main()
{
int fd = open("/dev/ttyS1", O_RDWR | O_NOCTTY | O_NDELAY);
set_opt(fd, 8, 0, 9600, 1, true);
char acBuf[1024] = {0};
while (1)
{
printf("Please input:\n");
memset(acBuf, 0, 1024);
scanf("%s", acBuf);
write(fd, acBuf, strlen(acBuf));
read(fd, acBuf, sizeof(acBuf));
printf("read data: %s\n", acBuf);
}
close(fd);
return 0;
}
利用串口,实现两台机器间的聊天程序serialchat
通过读取配置文件serial.cfg,获取初始化串口的数据
通过控制终端,实现聊天内容的输入和输出,完成自由聊天,如:
you say:hello!
he say:hello!
支持汉字聊天
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define BUF_LEN 1024
static int set_opt(int fd, int nSpeed, int nBits, char nEvent, int nStop)
{
struct termios newtio;
struct termios oldtio;
if(tcgetattr(fd,&oldtio) != 0)
{
perror("SetupSerial 1");
return -1;
}
bzero(&newtio,sizeof(newtio));
newtio.c_cflag |= CLOCAL |CREAD;
newtio.c_cflag &= ~CSIZE;
/***********数据位选择****************/
switch(nBits)
{
case 7:
newtio.c_cflag |= CS7;
break;
case 8:
newtio.c_cflag |= CS8;
break;
}
/***********校验位选择****************/
/***********校验位选择****************/
switch(nEvent)
{
case 'O':
case 'o':
newtio.c_cflag |= PARENB;
newtio.c_cflag |= PARODD;
newtio.c_iflag |= (INPCK | ISTRIP);
break;
case 'E':
case 'e':
newtio.c_iflag |= (INPCK |ISTRIP);
newtio.c_cflag |= PARENB;
newtio.c_cflag &= ~PARODD;
break;
case 'N':
case 'n':
newtio.c_cflag &= ~PARENB;
break;
case 'S':
case 's': /*as no parity*/
newtio.c_cflag &= ~PARENB;
newtio.c_cflag &= ~CSTOPB;
newtio.c_iflag |= INPCK;
break;
default:
return -1;
}
/***********波特率选择****************/
switch(nSpeed)
{
case 2400:
cfsetispeed(&newtio,B2400);
cfsetospeed(&newtio,B2400);
break;
case 4800:
cfsetispeed(&newtio,B4800);
cfsetospeed(&newtio,B4800);
break;
case 9600:
cfsetispeed(&newtio,B9600);
cfsetospeed(&newtio,B9600);
break;
case 57600:
cfsetispeed(&newtio,B57600);
cfsetospeed(&newtio,B57600);
break;
case 115200:
cfsetispeed(&newtio,B115200);
cfsetospeed(&newtio,B115200);
break;
case 460800:
cfsetispeed(&newtio,B460800);
cfsetospeed(&newtio,B460800);
break;
default:
cfsetispeed(&newtio,B9600);
cfsetospeed(&newtio,B9600);
break;
}
/***********停止位选择****************/
if(nStop == 1){
newtio.c_cflag &= ~CSTOPB;
}
else if(nStop ==2){
newtio.c_cflag |= CSTOPB;
}
newtio.c_cc[VTIME] = 150; //阻塞条件下有效
newtio.c_cc[VMIN] = 0;
tcflush(fd,TCIFLUSH);
if((tcsetattr(fd,TCSANOW,&newtio)) != 0)
{
perror("com set error");
return -1;
}
printf("set done!\n");
return 0;
}
int main(int argc, char *argv[])
{
int fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY );
if (fd < 0)
{
printf("Open Com error : %d, message : %s\n",errno, strerror(errno));
return -1;
}
set_opt(fd, 9600, 8, 'n',8);
if( fcntl(fd, F_SETFL, FNDELAY) < 0)
{
printf("set block error : %d\n",errno);
}
char buf[BUF_LEN] = {0};
int read_size = 0;
while(1)
{
printf("wait...\n");
read_size=read(fd, buf, BUF_LEN);
buf[read_size] = '\0';
printf("read size : %d, read data : \n%s", read_size,buf);
}
close(fd);
return 0;
}