#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);
}