填坑之串口接受数据不完整包的解决办法

填坑之串口接受数据不完整包的解决办法

通过串口收发包时,遇到了一个包多次才接收完整的问题,猜测是串口的接收buffer大小的问题,这种问题采取的是拼包的形式解决,代码看起来略微绕,主要是申请了一定大小的buffer,外加两个指针实现。代码如下:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define PACKET_SIZE 1024

unsigned int fp_count = 0,data_len = 0;

unsigned char data_buf[PACKET_SIZE] = {0};

static unsigned int covert16_to_10(char *s){

int sum = 0;

int size = 0;

int i = 0 ,j = 0;

unsigned char num[100] = {'\0'};

while(*s != '\0'){

num[size++] = *(s++);

}

if(num[0] == '0' && (num[1] == 'x' || num[1] == 'X'))

j = 2;

else if((num[0] >= 'a' && num[0] <= 'z') || (num[0] >= 'A' && num[0] <= 'Z')){

printf("Not is number\r\n");

return -1;

}

else if((num[0] >= '0' && num[0] <= '9')){

j = 0;

}

for(i = j;i < size;i++){

//printf("%c",num[i]);

if(num[i] >='0' &&num[i] <='9')

sum += (num[i] - '0') * pow(16,size-i-1);

if(num[i] >='a' &&num[i] <='f')

sum += (num[i] - 'a' + 10) * pow(16,size-i-1);

if(num[i] >='A' &&num[i] <='F')

sum += (num[i] - 'A' + 10) * pow(16,size-i-1);

}

//printf(" sum %d\n",sum);

return sum;

}

static int send_packet(unsigned char *buf,int len)

{

int ret = 0;

ret = write(g_dev.uart_fd,buf,len);

if(ret < 0){

pr_info("send packet faild");

return -1;

}

return ret;

}

int packet_parse(unsigned char *bd_buf)

{

}

int packet_handle(int fd)

{

int ret = 0,i = 0,j = 0;

int len = 0;

unsigned char tmp = 0;

unsigned char recv_buf[PACKET_SIZE] = {0};

unsigned char tmp_buf[PACKET_SIZE] = {0};

memset(recv_buf,0,PACKET_SIZE);

memset(tmp_buf,0,PACKET_SIZE);

ret = read(fd,recv_buf,sizeof(recv_buf));

if(ret < 0){

pr_info("bd read buf faild");

return ret;

}

#if 0

printf("ret %d\n",ret);

printf("recv_buf :%s\n",recv_buf);

#endif

if(data_len + ret >= PACKET_SIZE || fp_count >= PACKET_SIZE){

memset(data_buf,0,PACKET_SIZE);

data_len = 0;

fp_count = 0;

}

i = 0;

while(i < ret){

data_buf[data_len] = recv_buf[i];

i++;

data_len++;

}

#if 0

printf("data_buf :%s\n",data_buf);

printf("fp_count :%d\n",fp_count);

#endif

do_cpy:

i = fp_count;

tmp = 0;

while(tmp != '$' && i < data_len){

tmp = data_buf[i];

i++;

}

fp_count = i - 1;

#if 0

printf("fp_count :%d\n",fp_count);

printf("data_len :%d\n",data_len);

#endif

memset(tmp_buf,0,PACKET_SIZE);

i = fp_count;

j = 0;

tmp = 0;

tmp = data_buf[i++];

tmp_buf[j++] = tmp;

tmp = 0;

while(tmp != 0x0a && i < data_len ){

tmp = data_buf[i];

if(tmp == '$'){

fp_count = i;

i = 0;

goto do_cpy;

}

tmp_buf[j] = tmp;

i++;

j++;

}

#if 0

printf("tmp_buf :%s\n",tmp_buf);

printf("i :%d , j :%d\n",i,j);

#endif

if(tmp_buf[j-2] != 0x0d && tmp_buf[j-1] != 0x0a){

//printf("Invalid data\n");

return -1;

}

fp_count = i;

//printf("fp_count :%d\n",fp_count);

memset(recv_buf,0,PACKET_SIZE);

memcpy(recv_buf,tmp_buf,strlen((const char * )tmp_buf));

len = strlen((const char * )recv_buf);

if(recv_buf[0] == '$' && recv_buf[len - 2] == 0x0d && recv_buf[len - 1] == 0x0a){

//printf("recv_buf %s\n",recv_buf);

ret = bd_packet_parse(recv_buf);

if(ret < 0){

//pr_info("bd packet_parse faild");

return ret;

}

}

if(i < data_len){

goto do_cpy;

}

return ret;

}

packet_handle是主要的处理函数,拼包的代码就在这里,包头是$,结尾是0x0d 0x0a,具体可以分析代码

黄金推荐

《FASEB JOURNAL》数据统计
365bet体育投注地址

《FASEB JOURNAL》数据统计

✨ 08-12 💎 价值: 2865
jbl耳机和beats哪个好?jbl耳机和beats哪个音质好
365bet官方亚洲版

jbl耳机和beats哪个好?jbl耳机和beats哪个音质好

✨ 08-22 💎 价值: 6552
华为手机保修期多久
365bet体育投注地址

华为手机保修期多久

✨ 08-30 💎 价值: 7931