嵌入式linux串口通讯 阻塞 非阻塞
参考
(128条消息) linux下串口的阻塞和非阻塞操作_wuhengwudi的博客-CSDN博客_linux 阻塞 非阻塞
稍作修改 阻塞 非阻塞
#include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/wait.h> #include <sys/socket.h> #include <unistd.h> #include <arpa/inet.h> #include <fcntl.h> #include <asm/ioctls.h> #include <termios.h> #include <sys/stat.h> #include <limits.h> //编译 aarch64-linux-gnu-gcc -o t02_testserialRW testrw.c #define CSCS "AT+CSCS=\"GSM\"\r\n" #define BUFFER_SIZE 4096 char buff[BUFFER_SIZE]; static int setNewtio(int fd, int nSpeed, int nBits, char nEvent, float 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; //CLOCAL--忽略 modem 控制线,本地连线, 不具数据机控制功能, CREAD--使能接收标志 /***********数据位选择****************/ newtio.c_cflag &= ~CSIZE; switch(nBits) { case 8: newtio.c_cflag |= CS8; break; case 7: newtio.c_cflag |= CS7; break; case 6: newtio.c_cflag |= CS6; break; case 5: newtio.c_cflag |= CS5; break; default: newtio.c_cflag |= CS8; break; } /***********校验位选择****************/ switch(nEvent) { case 'N': /* 无校验 */ case 'n': newtio.c_cflag &= ~PARENB; break; case 'E': /* 偶校验 */ case 'e': newtio.c_cflag |= PARENB; newtio.c_cflag &= ~PARODD; break; case 'O': /* 奇校验 */ case 'o': newtio.c_cflag |= PARENB; newtio.c_cflag |= ~PARODD; break; case 'S': case 's': newtio.c_cflag &= ~PARENB; /*清除校验位 disable pairty checking Space校验 */ newtio.c_cflag &= ~CSTOPB; newtio.c_iflag |= INPCK; break; default: /* 其它选择为无校验 */ newtio.c_cflag &= ~PARENB; } /***********波特率选择****************/ 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; } /***********停止位选择****************/ int _nStop = (int)(nStop*10); switch(_nStop) { case 10: newtio.c_cflag &= ~CSTOPB; break; case 15: newtio.c_cflag &= ~CSTOPB; break; case 20: newtio.c_cflag |= CSTOPB; break; default: newtio.c_cflag &= ~CSTOPB; break; } /* //其他参数 newtio.c_cflag &= ~CRTSCTS; // 不使用硬件流控制 // IXON--启用输出的 XON/XOFF 流控制 // IXOFF--启用输入的 XON/XOFF 流控制 // IXANY--允许任何字符来重新开始输出 // IGNCR--忽略输入中的回车 newtio.c_iflag &= ~(IXON | IXOFF | IXANY); newtio.c_oflag &= ~OPOST; //启用输出处理 // ICANON--启用标准模式 (canonical mode)。允许使用特殊字符 EOF, EOL, // EOL2, ERASE, KILL, LNEXT, REPRINT, STATUS, 和 WERASE,以及按行的缓冲。 // ECHO--回显输入字符 // ECHOE--如果同时设置了 ICANON,字符 ERASE 擦除前一个输入字符,WERASE 擦除前一个词 // ISIG--当接受到字符 INTR, QUIT, SUSP, 或 DSUSP 时,产生相应的信号 newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); */ newtio.c_cc[VTIME] = 1; newtio.c_cc[VMIN] = 255; //阻塞条件下有效 tcflush(fd,TCIFLUSH); if((tcsetattr(fd,TCSANOW,&newtio)) != 0) { perror("com set error"); return -1; } printf("set done!\n"); return 0; } int main (int argc,char **argv) { printf("serial test version:0.0.17 [%s %s]\n", __DATE__, __TIME__); int fd; //串口返回值 int len; //串口收发数据 //初始化串口 fd = open("/dev/ttySAC5",O_RDWR|O_NOCTTY|O_NDELAY);//非阻塞 O_RDWR|O_NOCTTY|O_NDELAY if(fd<0){ printf("open port device error\n"); return -1; } if(setNewtio(fd,115200,8,'N',1) < 0) { printf("set uart1 arrt faile \n"); exit(-1); } if(argc>1){ if(fcntl(fd,F_SETFL,FNDELAY) < 0){ //非阻塞,覆盖前面open的属性 printf("fcntl failed\n"); } printf("set no block\n"); } else{//默认阻塞 if(fcntl(fd,F_SETFL,0) < 0){ //阻塞,即使前面在open串口设备时设置的是非阻塞的,这里设为阻塞后,以此为准 printf("fcntl failed\n"); } printf("set block\n"); } len = write(fd,CSCS,sizeof(CSCS)); printf(CSCS); if(len<0){ printf("write cscs erro\n"); return -1; } do { if(argc<=1)printf("TEST BLOCK\n"); memset(buff, 0, BUFFER_SIZE); if (read(fd, buff, BUFFER_SIZE) > 0) { printf("buff:%s\n", buff); len = write(fd,CSCS,sizeof(CSCS)); if(len<0){ printf("write buff error\n"); return -1; } } } while(strncmp(buff, "quit", 4)); printf("close\n"); close(fd); return 0; }
//