<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

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

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接

    有兩個可以進行控制串口阻塞性(同時控制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!\n");     
    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\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 plaincopy  
    1. 阻塞:fcntl(fd,F_SETFL,0)  
    [cpp] view plaincopy  
      1. 非阻塞:fcntl(fd,F_SETFL,FNDELAY)  
    RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全