生活随笔
收集整理的這篇文章主要介紹了
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
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 plaincopy
static?int?open_port(int?fd,int?comport)????? {??????? ?? ????if(comport?==?1)????? ????{????? ????????fd?=?open("/dev/ttyAT1",O_RDWR|O_NOCTTY|O_NDELAY);????? ????if(fd?==?-1){????? ????????perror("Can't?Open?Serial?Port");????? ????????return?-1;????? ????????}????? ????}????? ???? ????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;????? ????????}????? ????}????? ???? ????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)?? ????????{????? ????????????printf("fcntl?failed\n");????? ????????}????? ????????else{????? ????????printf("fcntl=%d\n",fcntl(fd,F_SETFL,FNDELAY));????? ????????}??? ????}?? ????else?? ????{?? ????????if(fcntl(fd,F_SETFL,0)?<?0){????? ????????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 plaincopy
阻塞:fcntl(fd,F_SETFL,0)??
[cpp]?view plaincopy
非阻塞:fcntl(fd,F_SETFL,FNDELAY) ?
總結
以上是生活随笔為你收集整理的linux下串口的阻塞和非阻塞操作的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。