zoukankan      html  css  js  c++  java
  • linux下串口的阻塞和非阻塞操作

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

    阻塞的定义:

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

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

    非阻塞的定义:

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

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

    [cpp] view plaincopy
     
    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! ");     
    92.     return 0;     
    93. }     
    [cpp] view plaincopy
     
    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 ");     
    35.         }     
    36.         else{     
    37.         printf("fcntl=%d ",fcntl(fd,F_SETFL,FNDELAY));     
    38.         }   
    39.     }  
    40.     else  
    41.     {  
    42.         if(fcntl(fd,F_SETFL,0) < 0){   //阻塞,即使前面在open串口设备时设置的是非阻塞的,这里设为阻塞后,以此为准  
    43.         printf("fcntl failed ");     
    44.         }     
    45.         else{     
    46.         printf("fcntl=%d ",fcntl(fd,F_SETFL,0));     
    47.         }   
    48.     }     
    49.     if(isatty(STDIN_FILENO) == 0){   
    50.         
    51.     printf("standard input is not a terminal device ");     
    52.     }     
    53.     else{     
    54.           
    55.         printf("isatty sucess! ");     
    56.     }    
    57.   
    58.     printf("fd-open=%d ",fd);     
    59.     return fd;     
    60. }  

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

    [cpp] view plaincopy
     
    1. 阻塞:fcntl(fd,F_SETFL,0)  
    [cpp] view plaincopy
     
      1. 非阻塞:fcntl(fd,F_SETFL,FNDELAY)  
  • 相关阅读:
    java如何得到GET和POST请求URL和参数列表
    Java中,当表单含有文件上传时,提交数据的如何读取
    图片文件,图片文件流和BASE64加密字符串之间的转换,以及图片的BASE64加密字符串再jsp上如何显示
    Multipart/form-data POST文件上传详解(转)
    如何控制微信分享网页时,展示的标题,描述和图片
    微信的分享功能(针对web手机站页面进行的分享功能)
    关于linux下内存使用的一些疑惑[转载]
    【转】《高级前端3.6》JavaScript多线程——Concurrent.Thread.js, WebWork
    【转】javascript中的LHS与RHS
    [转] linux系统中如何进入退出vim编辑器,方法及区别
  • 原文地址:https://www.cnblogs.com/lidabo/p/4573490.html
Copyright © 2011-2022 走看看