嵌入式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;
}
//

浙公网安备 33010602011771号