随笔小算法:从一个数据根据CRC校验出特定包

14 篇文章 2 订阅
10 篇文章 0 订阅
#define REC_BUFFSIZE 256
#define RECV_FRAME_MIN_LEN 5		//MODBUS响应帧的最小长度,异常反馈帧只有5B
#define RECV_FRAME_MAX_LEN 8		//信息帧最大8个字节(包括CRC16)
#define RETURN_OVERTIME 1			//uart1 485发送数据,超时响应定时器,单位s
#define UART1_BUFF_LEN 60			//串口1收的数据


void Track_cust_split_by_crc16(void* recv_data, kal_uint32 len)
{
    kal_uint8 *recv_data_ex = (kal_uint8*)recv_data;
    kal_uint8 *buffer = NULL;
    kal_uint32 buffer_offset = 0;
    kal_uint8 variable_len = 0;
    kal_uint8 * frame = NULL;
    kal_uint32 frame_len = 0;
    //kal_uint8 * data_content = NULL;
    //STRUCT_MODBUS_FC3_ADU_RSP  *fc3_adu_rsp = (STRUCT_MODBUS_FC3_ADU_RSP *)Ram_Alloc(5, sizeof(STRUCT_MODBUS_FC3_ADU_RSP));
    kal_uint16 crc16_val = 0;
    kal_uint16 crc16_val_tmp = 0;
    kal_uint8  crc16_len = 2;
    kal_uint8 temp_recv_data_ex[8] = {0};


    //LOGD(L_APP, L_V5, "len=%d", len);
    //LOGH(L_APP, L_V5, recv_data_ex, len);
    //1.判断接收到的数据是否为空
    if((recv_data_ex == NULL) || (len < RECV_FRAME_MIN_LEN))
    {
        //LOGD(L_APP, L_V5, "接收到的指令为空或者长度小于最小帧长度,丢弃不校验..");
        return;
    }

    //2.暂时分配MODBUS_REC_BUFFSIZE个字节
    buffer = (kal_uint8*)Ram_Alloc(5, REC_BUFFSIZE);
    memset(buffer, 0, REC_BUFFSIZE);


    //3.保证recv_data_ex能从buffer内存段的第buffer_index个开始赋值len个数据
    if((REC_BUFFSIZE - buffer_offset) >= len)
    {
        memcpy((buffer + buffer_offset), recv_data_ex, len);
    }
    else
    {
        return;
    }


    for(buffer_offset; buffer_offset <= (len - RECV_FRAME_MIN_LEN);)
    {
        for(variable_len = 0; variable_len <= (RECV_FRAME_MAX_LEN - RECV_FRAME_MIN_LEN); variable_len++)
        {
            if((frame = (kal_uint8 *)Ram_Alloc(5, RECV_FRAME_MIN_LEN + variable_len)) == NULL)
            {
                return;
            }
            memset(frame, 0, RECV_FRAME_MIN_LEN + variable_len);
            memcpy(frame, buffer + buffer_offset , RECV_FRAME_MIN_LEN + variable_len);

            crc16_val = CRC16_Modbus(frame, (RECV_FRAME_MIN_LEN + variable_len - crc16_len));
            //LOGD(L_APP, L_V5, "收到CRC数据:crc16_val=%x",crc16_val);

            crc16_val_tmp = (*(frame + RECV_FRAME_MIN_LEN + variable_len - 2));
            crc16_val_tmp = (crc16_val_tmp << 8) & 0XFF00;
            crc16_val_tmp |= (*(frame + RECV_FRAME_MIN_LEN + variable_len - 1));
            //LOGD(L_APP, L_V5, "收到CRC数据:crc16_val_tmp=%x",crc16_val_tmp);

            //LOGD(L_APP, L_V5, "crc16_val=%04X", crc16_val);
            //LOGD(L_APP, L_V5, "crc16_val_tmp=%04X", crc16_val_tmp);


            if(crc16_val == crc16_val_tmp)
            {
                LOGD(L_APP, L_V5, "crc16校验通过..");
                frame_len = RECV_FRAME_MIN_LEN + variable_len;

                //数据处理
#if defined(DRV_UART1_AS_485)
                track_drv_rs485_uart1_read_handle((kal_uint8*)frame, frame_len);
#endif
                Ram_Free(frame);
                break;

            }
            Ram_Free(frame);
        }


        if(variable_len >= (RECV_FRAME_MAX_LEN - RECV_FRAME_MIN_LEN))
        {
            buffer_offset ++;
        }
        else
        {
            //内存偏移到此帧尾部,默认为下一帧头部
            buffer_offset += (RECV_FRAME_MIN_LEN + variable_len);
        }
    }
    if(buffer_offset > (len - RECV_FRAME_MIN_LEN))
    {
        //LOGD(L_APP, L_V5, "crc16校验没有通过..");
    }

    Ram_Free(buffer);
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值