日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

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

發布時間:2023/12/9 linux 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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)?????
  • {???????
  • /***********打開串口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 plaincopy
  • 阻塞:fcntl(fd,F_SETFL,0)??
  • [cpp]?view plaincopy
  • 非阻塞:fcntl(fd,F_SETFL,FNDELAY) ?
  • 總結

    以上是生活随笔為你收集整理的linux下串口的阻塞和非阻塞操作的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。