Linux串口阻塞与非阻塞
Linux串口編程的阻塞與否可以在open函數(shù)中設置,例如:
打開時使用: fd = open(USAR1, O_RDWR | O_NOCTTY );//阻塞式讀寫fd = open("/dev/ttyAT2",O_RDWR|O_NOCTTY|O_NDELAY); //非阻塞讀寫除了用open函數(shù)之外還可以在open函數(shù)之后用fcntl函數(shù)來設置,代碼如下:
打開后使用fcntl函數(shù)修改: fcntl(fd, F_SETFL, 0); //設為阻塞,即使前面在open串口設備時設置的是非阻塞的,這里設為阻塞后,以此為準 fcntl(fd,F_SETFL,FNDELAY)//設為非阻塞,道理同上阻塞式讀寫可設置以下兩參數(shù):
opt.c_cc[VMIN] = vmin; ? //設置非規(guī)范模式下的超時時長和最小字符數(shù):阻塞模式起作用 opt.c_cc[VTIME] = vtime; //VTIME與VMIN配合使用,是指限定的傳輸或等待的最長時間若 VMIN = 0 ,VTIME = 0??,函數(shù)read未讀到任何參數(shù)也立即返回,相當于非阻塞模式;
若 VMIN = 0,???VTIME > 0??,函數(shù)read讀取到數(shù)據(jù)立即返回,若無數(shù)據(jù)則等待VTIME時間返回;
若 VMIN >?0,???VTIME =?0??,函數(shù)read()只有在讀取到VMIN個字節(jié)的數(shù)據(jù)或者收到一個信號的時候才返回;
若 VMIN >?0,???VTIME > 0??,從read讀取第一個字節(jié)的數(shù)據(jù)時開始計時,并會在讀取到VMIN個字節(jié)或者VTIME時間后返回。
?
例如,我在open函數(shù)設置為阻塞,并規(guī)定要接收到10字節(jié)后才返回read函數(shù),設置代碼如下:
int fd_uart; char *uart3 = "/dev/ttySAC3";if((fd_uart = open(uart3, O_RDWR|O_NOCTTY))<0)printf("open %s is failed",uart3);else{set_opt(fd_uart, 115200, 8, 'N', 1);}int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop) {struct termios newtio,oldtio;//讀出原來的配置信息,按理說之所以讀出來,是有部分數(shù)據(jù)不需要改,但感覺這里是這里對新的結構體配置,也沒用到讀出來的值if ( tcgetattr( fd,&oldtio) != 0) { perror("SetupSerial 1");return -1;}bzero( &newtio, sizeof( newtio ) ); //新結構體清0newtio.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 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] = 0;newtio.c_cc[VMIN] = 10; //設置阻塞的最小字節(jié)數(shù),阻塞條件下有效/*處理未接收字符*/ tcflush(fd,TCIFLUSH);/*激活新配置*/if((tcsetattr(fd,TCSANOW,&newtio))!=0){perror("com set error");return -1;}// printf("set done!\n\r");return 0; }參考文章:
https://blog.csdn.net/m0_38096844/article/details/90716182
https://blog.csdn.net/wuhengwudi/article/details/7454629
總結
以上是生活随笔為你收集整理的Linux串口阻塞与非阻塞的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 从0到1写RT-Thread内核——支持
- 下一篇: 烈火红岩剧情介绍