linux下串口的阻塞和非阻塞操作

简介: 有两个可以进行控制串口阻塞性(同时控制read和write):一个是在打开串口的时候,open函数是否带O_NDELAY;第二个是可以在打开串口之后通过fcntl()函数进行控制。 阻塞的定义:        对于read,block指当串口输入缓冲区没有数据的时候,read函数将会阻塞在这里,移植到串口输入缓冲区中有数据可读取,read读到了需要的字节数之后,返回值为读到的字节数; 对于write,block指当串口输出缓冲区满,或剩下的空间小于将要写入的字节数,则write将阻塞,一直到串口输出缓冲区中剩下的空间大于等于将要写入的字节数,执行写入操作,返回写入的字节数。

有两个可以进行控制串口阻塞性(同时控制read和write):一个是在打开串口的时候,open函数是否带O_NDELAY;第二个是可以在打开串口之后通过fcntl()函数进行控制。

阻塞的定义:

       对于read,block指当串口输入缓冲区没有数据的时候,read函数将会阻塞在这里,移植到串口输入缓冲区中有数据可读取,read读到了需要的字节数之后,返回值为读到的字节数;

对于write,block指当串口输出缓冲区满,或剩下的空间小于将要写入的字节数,则write将阻塞,一直到串口输出缓冲区中剩下的空间大于等于将要写入的字节数,执行写入操作,返回写入的字节数。

非阻塞的定义:

对于read,no block指当串口输入缓冲区没有数据的时候,read函数立即返回,返回值为0。

对于write,no block指当串口输出缓冲区满,或剩下的空间小于将要写入的字节数,则write将进行写操作,写入当前串口输出缓冲区剩下空间允许的字节数,然后返回写入的字节数。

 

[cpp]  view plain copy
 
  1. static int set_opt(int fd, int nSpeed, int nBits, char nEvent, int nStop)     
  2. {     
  3.     struct termios newtio;     
  4.     struct termios oldtio;     
  5.          
  6.     if(tcgetattr(fd,&oldtio) != 0)     
  7.     {     
  8.         perror("SetupSerial 1");     
  9.         return -1;     
  10.     }     
  11.          
  12.     bzero(&newtio,sizeof(newtio));     
  13.     newtio.c_cflag |= CLOCAL |CREAD;     
  14.     newtio.c_cflag &= ~CSIZE;     
  15.       
  16. /***********数据位选择****************/      
  17.     switch(nBits)     
  18.     {     
  19.         case 7:     
  20.         newtio.c_cflag |= CS7;     
  21.         break;     
  22.         case 8:     
  23.         newtio.c_cflag |= CS8;     
  24.         break;         
  25.     }     
  26. /***********校验位选择****************/    
  27.     switch(nEvent)     
  28.     {     
  29.         case 'O':     
  30.         newtio.c_cflag |= PARENB;     
  31.         newtio.c_cflag |= PARODD;     
  32.         newtio.c_iflag |= (INPCK | ISTRIP);     
  33.             break;     
  34.         case 'E':     
  35.         newtio.c_iflag |= (INPCK |ISTRIP);     
  36.         newtio.c_cflag |= PARENB;     
  37.         newtio.c_cflag &= ~PARODD;     
  38.             break;     
  39.          case 'N':     
  40.         newtio.c_cflag &= ~PARENB;     
  41.             break;     
  42.     }     
  43. /***********波特率选择****************/     
  44.     switch(nSpeed)     
  45.     {     
  46.         case 2400:     
  47.         cfsetispeed(&newtio,B2400);     
  48.         cfsetospeed(&newtio,B2400);     
  49.             break;     
  50.          case 4800:     
  51.         cfsetispeed(&newtio,B4800);     
  52.         cfsetospeed(&newtio,B4800);     
  53.             break;     
  54.          case 9600:     
  55.         cfsetispeed(&newtio,B9600);     
  56.         cfsetospeed(&newtio,B9600);     
  57.             break;   
  58.          case 57600:     
  59.         cfsetispeed(&newtio,B57600);     
  60.         cfsetospeed(&newtio,B57600);     
  61.             break;     
  62.          case 115200:     
  63.         cfsetispeed(&newtio,B115200);     
  64.         cfsetospeed(&newtio,B115200);     
  65.             break;     
  66.          case 460800:     
  67.         cfsetispeed(&newtio,B460800);     
  68.         cfsetospeed(&newtio,B460800);     
  69.             break;               
  70.          default:     
  71.         cfsetispeed(&newtio,B9600);     
  72.         cfsetospeed(&newtio,B9600);     
  73.                 break;     
  74.     }     
  75. /***********停止位选择****************/    
  76.     if(nStop == 1){     
  77.         newtio.c_cflag &= ~CSTOPB;     
  78.     }     
  79.     else if(nStop ==2){     
  80.         newtio.c_cflag |= CSTOPB;     
  81.     }     
  82.     newtio.c_cc[VTIME] = 1;     
  83.     newtio.c_cc[VMIN] = FRAME_MAXSIZE;   //阻塞条件下有效  
  84.     
  85.     tcflush(fd,TCIFLUSH);     
  86.     if((tcsetattr(fd,TCSANOW,&newtio)) != 0)     
  87.     {     
  88.         perror("com set error");     
  89.         return -1;     
  90.     }     
  91.     printf("set done!\n");     
  92.     return 0;     
  93. }     

 

[cpp]  view plain copy
 
  1. static int open_port(int fd,int comport)     
  2. {       
  3. /***********打开串口1****************/  
  4.     if(comport == 1)     
  5.     {     
  6.         fd = open("/dev/ttyAT1",O_RDWR|O_NOCTTY|O_NDELAY);     
  7.     if(fd == -1){     
  8.         perror("Can't Open Serial Port");     
  9.         return -1;     
  10.         }     
  11.     }     
  12.  /***********打开串口2****************/   
  13.     else if(comport == 2)     
  14.     {     
  15.         fd = open("/dev/ttyAT2",O_RDWR|O_NOCTTY|O_NDELAY);     
  16.         if(fd == -1){     
  17.             perror("Can't Open Serial Port");     
  18.             return -1;     
  19.         }     
  20.     }     
  21. /***********打开串口3****************/    
  22.     else if(comport == 3)     
  23.     {     
  24.         fd = open("/dev/ttyAT3",O_RDWR|O_NOCTTY|O_NDELAY);     
  25.         if(fd == -1){     
  26.             perror("Can't Open Serial Port");     
  27.             return -1;     
  28.         }     
  29.     }     
  30.     if(comport == 1)  
  31.     {  
  32.         if(fcntl(fd,F_SETFL,FNDELAY) < 0)//非阻塞,覆盖前面open的属性  
  33.         {     
  34.             printf("fcntl failed\n");     
  35.         }     
  36.         else{     
  37.         printf("fcntl=%d\n",fcntl(fd,F_SETFL,FNDELAY));     
  38.         }   
  39.     }  
  40.     else  
  41.     {  
  42.         if(fcntl(fd,F_SETFL,0) < 0){   //阻塞,即使前面在open串口设备时设置的是非阻塞的,这里设为阻塞后,以此为准  
  43.         printf("fcntl failed\n");     
  44.         }     
  45.         else{     
  46.         printf("fcntl=%d\n",fcntl(fd,F_SETFL,0));     
  47.         }   
  48.     }     
  49.     if(isatty(STDIN_FILENO) == 0){   
  50.         
  51.     printf("standard input is not a terminal device\n");     
  52.     }     
  53.     else{     
  54.           
  55.         printf("isatty sucess!\n");     
  56.     }    
  57.   
  58.     printf("fd-open=%d\n",fd);     
  59.     return fd;     
  60. }  

 

所以,linux的串口的阻塞性通过fcntl()函数进行设置即可。

 

[cpp]  view plain copy
 
  1. 阻塞:fcntl(fd,F_SETFL,0)  
[cpp]  view plain copy
 
    1. 非阻塞:fcntl(fd,F_SETFL,FNDELAY)  
目录
相关文章
|
2月前
|
网络协议 Linux 网络安全
入职必会-开发环境搭建39-Linux常用操作-Linux防火墙操作
在CentOS 7中,新引入了firewalld服务(防火墙),取代了CentOS 6之前的iptables服务(防火墙)。
入职必会-开发环境搭建39-Linux常用操作-Linux防火墙操作
|
2月前
|
存储 运维 Linux
Linux磁盘精准缩容:操作详解与技巧
在Linux系统管理中,有效的磁盘空间优化对于维护系统性能至关重要。本文将深入探讨如何在Linux环境下安全地进行磁盘缩容,帮助你合理调整存储资源,确保系统高效运行。跟随本篇的步骤,一起优化你的Linux系统磁盘空间!
Linux磁盘精准缩容:操作详解与技巧
|
1月前
|
Linux 开发者
深入理解Linux I/O模型:同步、异步、阻塞与非阻塞
【8月更文挑战第1天】在探索操作系统的奥秘中,I/O模型作为影响性能的关键因素之一,常常让开发者们感到困惑。本文将通过浅显易懂的语言和实际代码示例,揭示Linux下同步与异步、阻塞与非阻塞的概念及其区别,并指导如何在实际应用中选择合适的I/O模型以优化程序性能。
57 1
|
2月前
|
缓存 网络协议 算法
【Linux系统编程】深入剖析:四大IO模型机制与应用(阻塞、非阻塞、多路复用、信号驱动IO 全解读)
在Linux环境下,主要存在四种IO模型,它们分别是阻塞IO(Blocking IO)、非阻塞IO(Non-blocking IO)、IO多路复用(I/O Multiplexing)和异步IO(Asynchronous IO)。下面我将逐一介绍这些模型的定义:
128 1
|
3月前
|
Linux 网络安全 开发工具
Linux 管理远程会话 screen:掌握终端的多任务操作
`Linux screen` 命令让多任务管理变得更简单,尤其在SSH连接远程服务器时。创建新会话如`screen -S backup`,查看会话`screen -ls`,退出`exit`。高级功能包括直接在会话中运行命令,如`screen vim memo.txt`,会话共享以协同工作,以及通过`screen -r`或`-D -r`重新连接或强制恢复断开的会话。提高效率,确保任务不间断运行。
51 1
|
2月前
|
安全 固态存储 Linux
服务器linux操作系统重装的完整流程-傻瓜式教学
服务器linux操作系统重装的完整流程-傻瓜式教学
|
3月前
|
Linux C++
Linux C/C++目录和文件的更多操作
Linux C/C++目录和文件的更多操作
|
3月前
|
Ubuntu Linux
服务器硬件 做raid操作 ubuntu linux做raid
服务器硬件 做raid操作 ubuntu linux做raid
55 0
|
3月前
|
SQL 关系型数据库 MySQL
Linux 下mysql操作
Linux 下mysql操作
33 0