串口数据解析总结
在linux下编写串口通讯程序,采用select监听串口的可读事件,一旦可读,调用read。但是我们会发现,read一次得到的数据通常不是完整的一个数据帧。
比如完整数据帧为
但是实际上需要read多次才能完全读到。
程序实际运行情况:
两次读完:
四次读完:
为了解决不能接收完整数据帧的问题,借鉴了网友的例子,并进行了一些改动:
现在的效果:
下面是程序代码:
#include "smartlight.h"
int portfd = -1;
void print_frame(const char *desc,uint8_t *buf,int size);
void getCompleteFrame(uint8_t *inBuf,int inCnt,uint8_t *outBuf,int *destCnt,int *readStatus);
void *monitor_serial_readable(void *arg);
int main(int argc,char *argv[])
{
int nret;
pthread_t wtid;
/* open serial port */
portfd = open_port();
/* set serial port */
set_opt(portfd,57600);
nret = pthread_create(&wtid,NULL,monitor_serial_readable,NULL);
if(nret != 0)
{
DEBUG_ERR(create thread failed);
exit(-1);
}
nret = pthread_join(wtid,NULL);
if(nret != 0)
{
DEBUG_ERR(join thread failed);
exit(-1);
}
close(portfd);
return 0;
}
void getCompleteFrame(uint8_t *inBuf,int inCnt,uint8_t *outBuf,int *destCnt,int *readStatus)
{
int i;
for(i=0; i<inCnt; i++)
{
if(inBuf[i] == 0x11 && inBuf[i+2] == 0x00 && inBuf[i+3] == 0x00)//header
{
outBuf[(*destCnt)++] = inBuf[i];
*readStatus = 1;
//print_frame("header",dest,dest_cnt);
continue;
}
if(*readStatus == 1)//body
{
outBuf[(*destCnt)++] = inBuf[i];
//print_frame("body",dest,dest_cnt);
}
if(*destCnt == outBuf[1])//tail
{
print_frame("tail",outBuf,*destCnt);
*readStatus = 0;
*destCnt = 0;
memset(outBuf,-1,sizeof(outBuf));
memset(inBuf,0,sizeof(inBuf));
continue;
}
}
}
void *monitor_serial_readable(void *arg)
{
int rc,i,nread=0;
fd_set rset;
struct timeval tv;
uint8_t buf[1024] = {0};
uint8_t dest[1024]={0};
int read_status = 0;
int dest_cnt = 0;
while(1)
{
FD_ZERO(&rset);
FD_SET(portfd,&rset);
tv.tv_sec = 5;
tv.tv_usec = 0;
rc = select(portfd+1,&rset,NULL,NULL,&tv);
if(rc == -1)
{
DEBUG_ERR(select error in thread);
continue;
}
if(rc == 0)
{
DEBUG_INFO(select timeout in thread);
continue;
}
else
{
nread = read(portfd,buf,sizeof(buf));
if(nread == -1)
{
perror("read");
usleep(100*1000);
continue;
}
if(nread == 0)
{
printf("nread==0\n");
usleep(100*1000);
continue;
}
printf("nread = %d\n",nread);
getCompleteFrame(buf,nread,dest,&dest_cnt,&read_status);
}
}//END_while
}
void print_frame(const char *desc,uint8_t *buf,int size)
{
int i;
printf(RED"[%s] [LEN=%d]"COLOR_END,desc,size);
for(i=0; i<size; i++)
{
printf(BLUE"[%.2x]"COLOR_END,buf[i]);
}
printf("\n");
}
作者:白菜菜白
出处:http://www.cnblogs.com/lvchaoshun/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。