串口助手发送八个字节,linux接收并打印。必须发送8个字节(这是bug。当然也可以在程序里改成必须发送9个字节)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <sys/epoll.h>
#define MAXEVENTS 64
int fd;
int efd;
void pthread_uartrecv(void)
{
int n,i,nread,s;
char buff[20];
struct epoll_event event;
struct epoll_event* events;
events=calloc(MAXEVENTS,sizeof event);
efd=epoll_create(5);//epoll support number is 5
event.data.fd=fd;
event.events=EPOLLIN|EPOLLET; //et mod,put in data
s=epoll_ctl(efd,EPOLL_CTL_ADD,fd,&event);
while(1)
{
int len=0;
bzero(buff,8);
while(1)
{
n=epoll_wait(efd,events,MAXEVENTS,-1);// -1 :wait until it happen
for(i=0;i<n;i++)
{
if((events[i].events & EPOLLERR)||(events[i].events & EPOLLHUP)||(!(events[i].events & EPOLLIN)))
{
fprintf(stderr,"epoll error\n");
close(events[i].data.fd);
continue;
}
else
{
nread = read(events[i].data.fd,buff+len,8);
tcdrain(fd);
tcflush(fd,TCIOFLUSH);
len=len+nread;
printf("nread=%d,len=%d\n",nread,len);
}
}
if(len>=8)
break;
}
printf("%s\n",buff);
}
}
int main()
{
int flags;
struct termios opt;
//fd = open("/dev/ttyUSB0", O_RDWR|O_NOCTTY|O_NDELAY);
fd = open("/dev/ttyUSB0", O_RDWR|O_NOCTTY|O_NONBLOCK);
//fcntl(fd, F_SETFL, 0);
//flags=fcntl(fd, F_GETFL, 0);
//flags|=O_NONBLOCK;
//fcntl(fd, F_SETFL, flags);
tcgetattr(fd, &opt);
cfsetispeed(&opt, B9600);
cfsetospeed(&opt, B9600);
if(tcsetattr(fd, TCSANOW, &opt) != 0 )
{
perror("tcsetattr error1");
return -1;
}
opt.c_cflag &= ~CSIZE;
opt.c_cflag |= CS8;
opt.c_cflag &= ~CSTOPB;
opt.c_cflag &= ~PARENB;
opt.c_iflag &= ~INPCK;//opt.c_cflag &= ~INPCK;the last this is fetal set
opt.c_cflag |= (CLOCAL | CREAD);
opt.c_cflag &= ~CRTSCTS;
opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
opt.c_oflag &= ~OPOST;
opt.c_oflag &= ~(ONLCR | OCRNL); //添加的
opt.c_iflag &= ~(ICRNL | INLCR);
opt.c_iflag &= ~(IXON | IXOFF | IXANY); //添加的
opt.c_cc[VTIME] = 8;
opt.c_cc[VMIN] = 10;
tcflush(fd, TCIOFLUSH);
printf("configure complete\n");
if(tcsetattr(fd, TCSANOW, &opt) != 0)
{
perror("serial error");
return -1;
}
pthread_t id;
pthread_create(&id,NULL,(void*)pthread_uartrecv,NULL);
while(1)
{
sleep(2);
printf("this is main function\n");
}
}
为了改善上述bug
void pthread_uartrecv(void)
{
int n,i,nread,s;
char buff[20];
struct epoll_event event;
struct epoll_event* events;
events=calloc(MAXEVENTS,sizeof event);
efd=epoll_create(5);//epoll support number is 5
event.data.fd=fd;
event.events=EPOLLIN|EPOLLET; //et mod,put in data
s=epoll_ctl(efd,EPOLL_CTL_ADD,fd,&event);
while(1)
{
int len=0;
bzero(buff,20);
while(1)
{
//printf("here epoll_wait\n");
n=epoll_wait(efd,events,MAXEVENTS,20);// -1 :wait until it happen
for(i=0;i<n;i++)
{
nread = read(events[i].data.fd,buff+len,20);
if(nread>0)
{
tcdrain(fd);
tcflush(fd,TCIOFLUSH);
len=len+nread;
printf("nread=%d,len=%d\n",nread,len);
}
}
if(n==0)
{
break;
}
}
if(len>0)
printf("%s\n",buff);
}
}
或者 封装成函数
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <sys/epoll.h>
#define MAXEVENTS 64
int fd;
int efd;
//
int epoll_read(char *buff,int datalen)
{
int n,i,nread,len;
struct epoll_event event;
struct epoll_event* events;
events=calloc(MAXEVENTS,sizeof event);
efd=epoll_create(5);//epoll support number is 5
event.data.fd=fd;
event.events=EPOLLIN|EPOLLET; //et mod,put in data
epoll_ctl(efd,EPOLL_CTL_ADD,fd,&event);
len=0;
while(1)
{
n=epoll_wait(efd,events,MAXEVENTS,20);// -1 :wait until it happen
for(i=0;i<n;i++)
{
nread = read(events[i].data.fd,buff+len,datalen);
if(nread>0)
{
tcdrain(fd);
tcflush(fd,TCIOFLUSH);
len=len+nread;
printf("nread=%d,len=%d\n",nread,len);
}
}
if(n==0)
{
break;
}
}
free(events);
close(efd); //please close efd after used epoll 这是易错点,否则会导致后面无法接收串口数据
return len;
}
void pthread_uartrecv(void)
{
char buff[20];
while(1)
{
int len=0;
bzero(buff,20);
len=epoll_read(buff,20);
if(len>0)
printf("len=%d,buff=%s\n",len,buff);
}
}
int main()
{
int flags;
struct termios opt;
//fd = open("/dev/ttyUSB0", O_RDWR|O_NOCTTY|O_NDELAY);
fd = open("/dev/ttyUSB0", O_RDWR|O_NOCTTY|O_NONBLOCK);
//fcntl(fd, F_SETFL, 0);
//flags=fcntl(fd, F_GETFL, 0);
//flags|=O_NONBLOCK;
//fcntl(fd, F_SETFL, flags);
tcgetattr(fd, &opt);
cfsetispeed(&opt, B9600);
cfsetospeed(&opt, B9600);
if(tcsetattr(fd, TCSANOW, &opt) != 0 )
{
perror("tcsetattr error1");
return -1;
}
opt.c_cflag &= ~CSIZE;
opt.c_cflag |= CS8;
opt.c_cflag &= ~CSTOPB;
opt.c_cflag &= ~PARENB;
opt.c_iflag &= ~INPCK;//opt.c_cflag &= ~INPCK;the last this is fetal set
opt.c_cflag |= (CLOCAL | CREAD);
opt.c_cflag &= ~CRTSCTS;
opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
opt.c_oflag &= ~OPOST;
opt.c_oflag &= ~(ONLCR | OCRNL); //添加的
opt.c_iflag &= ~(ICRNL | INLCR);
opt.c_iflag &= ~(IXON | IXOFF | IXANY); //添加的
opt.c_cc[VTIME] = 8;
opt.c_cc[VMIN] = 10;
tcflush(fd, TCIOFLUSH);
printf("configure complete\n");
if(tcsetattr(fd, TCSANOW, &opt) != 0)
{
perror("serial error");
return -1;
}
pthread_t id;
pthread_create(&id,NULL,(void*)pthread_uartrecv,NULL);
while(1)
{
sleep(2);
printf("this is main function\n");
}
}