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

來源:互聯網
上載者:User
    有兩個可以進行控制串口阻塞性(同時控制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 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':              newtio.c_cflag |= PARENB;              newtio.c_cflag |= PARODD;              newtio.c_iflag |= (INPCK | ISTRIP);                  break;              case 'E':              newtio.c_iflag |= (INPCK |ISTRIP);              newtio.c_cflag |= PARENB;              newtio.c_cflag &= ~PARODD;                  break;               case 'N':              newtio.c_cflag &= ~PARENB;                  break;          }      /***********傳輸速率選擇****************/          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] = 1;          newtio.c_cc[VMIN] = FRAME_MAXSIZE;   //阻塞條件下有效            tcflush(fd,TCIFLUSH);          if((tcsetattr(fd,TCSANOW,&newtio)) != 0)          {              perror("com set error");              return -1;          }          printf("set done!\n");          return 0;      }     
[cpp] view plain copy static int open_port(int fd,int comport)      {        /***********開啟串口1****************/       if(comport == 1)          {              fd = open("/dev/ttyAT1",O_RDWR|O_NOCTTY|O_NDELAY);          if(fd == -1){              perror("Can't Open Serial Port");              return -1;              }          }       /***********開啟串口2****************/        else if(comport == 2)          {              fd = open("/dev/ttyAT2",O_RDWR|O_NOCTTY|O_NDELAY);              if(fd == -1){                  perror("Can't Open Serial Port");                  return -1;              }          }      /***********開啟串口3****************/         else if(comport == 3)          {              fd = open("/dev/ttyAT3",O_RDWR|O_NOCTTY|O_NDELAY);              if(fd == -1){                  perror("Can't Open Serial Port");                  return -1;              }          }          if(comport == 1)       {           if(fcntl(fd,F_SETFL,FNDELAY) < 0)//非阻塞,覆蓋前面open的屬性           {                  printf("fcntl failed\n");              }              else{              printf("fcntl=%d\n",fcntl(fd,F_SETFL,FNDELAY));              }        }       else       {           if(fcntl(fd,F_SETFL,0) < 0){   //阻塞,即使前面在open串口裝置時設定的是非阻塞的,這裡設為阻塞後,以此為準           printf("fcntl failed\n");              }              else{              printf("fcntl=%d\n",fcntl(fd,F_SETFL,0));              }        }          if(isatty(STDIN_FILENO) == 0){                 printf("standard input is not a terminal device\n");          }          else{                         printf("isatty sucess!\n");          }            printf("fd-open=%d\n",fd);          return fd;      }  

所以,linux的串口的阻塞性通過fcntl()函數進行設定即可。

[cpp] view plain copy 阻塞:fcntl(fd,F_SETFL,0)   [cpp] view plain copy 非阻塞:fcntl(fd,F_SETFL,FNDELAY) 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.