epoll机制读取linux串口数据
https://blog.csdn.net/coding__madman/article/details/51657944
com.c
#include "com.h"
int openSerial(char *cSerialName)
{
int iFd;
struct termios opt;
iFd = open(cSerialName, O_RDWR | O_NOCTTY |O_NONBLOCK);
//iFd = open(cSerialName, O_RDWR | O_NOCTTY | O_NDELAY);//阻塞 |O_RSYNC
if(iFd < 0) {
perror(cSerialName);
return -1;
}
tcgetattr(iFd, &opt);
cfsetispeed(&opt, B9600);
cfsetospeed(&opt, B9600);
/*
* raw mode
*/
opt.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
opt.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
opt.c_oflag &= ~(OPOST);
opt.c_cflag &= ~(CSIZE | PARENB);
opt.c_cflag |= CS8;
/*
* 'DATA_LEN' bytes can be read by serial
*/
opt.c_cc[VMIN] = DATA_LEN;
opt.c_cc[VTIME] = 150;
if (tcsetattr(iFd, TCSANOW, &opt)<0) {
return -1;
}
return iFd;
}
int EpollInit(int cfd)
{
epid = epoll_create(6);//放在初始化
event.events = EPOLLET | EPOLLIN;
event.data.fd = cfd;
if (epoll_ctl(epid, EPOLL_CTL_ADD, cfd, &event) != 0) {//将读事件添加到epoll的事件队列中
printf("set epoll error!\n");
return 0;
}
printf("set epoll ok!\n");
return 1;
}
int ComRead(char * ReadBuff,const int ReadLen)
{
int read_len = 0;
int len = 0;
//下面开始epoll等待
int i =0,witeNum= 0;
while (1)
{
witeNum = epoll_wait(epid, events, 1, 50);
printf("witeNum0 = %d\n ", witeNum);
if( witeNum == 0)
return 0;
//printf("witeNum = %d\n", witeNum);
for (i = 0; i < witeNum; i++)
{
if ((events[i].events & EPOLLERR)
|| (events[i].events & EPOLLHUP)
|| (!(events[i].events & EPOLLIN)))
{
printf("no data!\n");
break;
}
else if (events[i].events & EPOLLIN)
{//有数据进入 接受数据
len = read(events[i].data.fd, ReadBuff, ReadLen);
tcdrain(fd);
tcflush(fd,TCIOFLUSH);
if(len != ReadLen) //如何保证每次都读到这些字节又不阻塞!
{
bzero(ReadBuff,15);
}
if( len == ReadLen)
return len;
}
}
}
return len ;
}
com.h
#ifndef _COM_H_
#define _COM_H_
#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 <limits.h>
#include <asm/ioctls.h>
#include <time.h>
#include <pthread.h>
#include <sys/ioctl.h>
#include <sys/epoll.h>
#include <string.h>
//#define MAXLEN 15
#define DATA_LEN 0xFF
int fd;//文件描述符
int epid; //epoll标识符
struct epoll_event event;
struct epoll_event events[6];//事件集合
//char RecvBuff[MAXLEN];//接受到的数据
int ComRead(char * ReadBuff,const int ReadLen);//com口读数据
int EpollInit(int cfd);
int openSerial(char *cSerialName);
#endif
main.c
#include <stdio.h>
#include "com.h"
int main(void)
{
char tmp[15] = {0};
int rl;
int write_len;
char* text = ".P\r\n" ;
int i;
fd = openSerial("/dev/ttySP2");
if(fd < 0)
{
printf("open com fail!\n");
return 0;
}
EpollInit(fd);
while(1)
{
bzero(tmp,sizeof(tmp));
tcflush(fd,TCIOFLUSH);//清空串口输入输出缓存
write_len = write(fd, text, strlen(".P\r\n"));//向串口发送指令
if(write_len != 4)
{
printf("write fail!\n");
return 0;
}
rl = ComRead(tmp,8);//读取8个字节放到缓存
//打印读到的数据
printf("write_len = %d, read_len = %d\n", write_len, rl);
tmp[rl] = '\0';
printf("read: %s\n", tmp);
for(i = 0; i < rl; i++)
printf(" %d", tmp[i]);
printf("\n\n");
if(rl != 8)
{
printf("read fail!\n");
}
}
close(epid);
close(fd);
return 0;
}