180 lines
7.3 KiB
C
180 lines
7.3 KiB
C
#include "../inc/data_type_def.h"
|
||
#include "../inc/log.h"
|
||
#include "../inc/osel_arch.h"
|
||
#include "../inc/data_analysis.h"
|
||
#define UART_RXSIZE (254U)
|
||
#define UART_DATA_ANALYSIS_PORT_1 DATA_1
|
||
#define UART_DATA_ANALYSIS_PORT_2 DATA_2
|
||
|
||
static data_interupt_cb_t uart_data_analysis_cb = NULL; // 数据源中断回调函数
|
||
|
||
static void data_analysis_event1(void)
|
||
{
|
||
uint8_t frame[UART_RXSIZE];
|
||
uint8_t data_head[3];
|
||
uint8_t crc[2];
|
||
uint16_t frame_len, out_frame_len;
|
||
data_read(UART_DATA_ANALYSIS_PORT_1, &data_head[0], 3);
|
||
osel_memcpy((uint8_t *)&frame_len, &data_head[1], 2);
|
||
|
||
frame_len = B2S_UINT16(frame_len) - 2; // 报文长度包含帧长,这里需要减2
|
||
if (frame_len > UART_RXSIZE)
|
||
{
|
||
lock_data(UART_DATA_ANALYSIS_PORT_1);
|
||
unlock_data(UART_DATA_ANALYSIS_PORT_1);
|
||
return;
|
||
}
|
||
|
||
out_frame_len = data_read(UART_DATA_ANALYSIS_PORT_1, frame, (uint16_t)frame_len);
|
||
if (out_frame_len != frame_len)
|
||
{
|
||
return;
|
||
}
|
||
out_frame_len = out_frame_len - 1; // 报文中包含帧尾,这里需要减1
|
||
|
||
// 校验CRC_16
|
||
uint16_t crc_16 = 0;
|
||
uint16_t crc16 = crc16_compute(&frame[0], out_frame_len - 2);
|
||
osel_memcpy(&crc[0], &frame[out_frame_len - 2], 2);
|
||
crc_16 = BUILD_UINT16(crc[1], crc[0]);
|
||
if (crc16 != crc_16)
|
||
{
|
||
return;
|
||
}
|
||
// CRC校验通过后将数据长度-2
|
||
out_frame_len -= 2;
|
||
|
||
LOG_PRINT("data_analysis_event1 ok:");
|
||
LOG_HEX(frame, out_frame_len);
|
||
}
|
||
|
||
static void data_analysis_event2(void)
|
||
{
|
||
uint8_t frame[UART_RXSIZE];
|
||
uint8_t data_head[4];
|
||
uint8_t crc[2];
|
||
uint16_t frame_len, out_frame_len;
|
||
data_read(UART_DATA_ANALYSIS_PORT_2, &data_head[0], 4);
|
||
osel_memcpy((uint8_t *)&frame_len, &data_head[2], 2);
|
||
frame_len = B2S_UINT16(frame_len);
|
||
if (frame_len > UART_RXSIZE)
|
||
{
|
||
lock_data(UART_DATA_ANALYSIS_PORT_2);
|
||
unlock_data(UART_DATA_ANALYSIS_PORT_2);
|
||
return;
|
||
}
|
||
|
||
out_frame_len = data_read(UART_DATA_ANALYSIS_PORT_2, frame, (uint16_t)frame_len);
|
||
if (out_frame_len != frame_len)
|
||
{
|
||
printf("out_frame_len:%d, frame_len:%d\n", out_frame_len, frame_len);
|
||
return;
|
||
}
|
||
|
||
// 校验CRC_16
|
||
uint16_t crc_16 = 0;
|
||
uint16_t crc16 = crc16_compute(&frame[0], out_frame_len - 2);
|
||
osel_memcpy(&crc[0], &frame[out_frame_len - 2], 2);
|
||
crc_16 = BUILD_UINT16(crc[1], crc[0]);
|
||
if (crc16 != crc_16)
|
||
{
|
||
LOG_PRINT("crc error crc16:%x, crc_16:%x\n");
|
||
return;
|
||
}
|
||
|
||
out_frame_len -= 2; // 去掉CRC_16
|
||
|
||
LOG_PRINT("data_analysis_event2 ok:");
|
||
LOG_HEX(frame, out_frame_len);
|
||
}
|
||
/**
|
||
* @brief 需要识别帧头和帧尾的数据协议
|
||
* @return {*}
|
||
* @note
|
||
*/
|
||
static void data_register1(void)
|
||
{
|
||
/**
|
||
* 帧头 帧长度 源地址 目标地址 报文类型 报文体 校验 帧尾
|
||
1 2 2 2 1 n 2 1
|
||
*/
|
||
#define FRAME_HEAD 0x05 // 帧头
|
||
#define FRAME_TAIL 0x1b // 帧尾
|
||
|
||
// 注册数据解析
|
||
data_reg_t reg;
|
||
reg.sd.valid = TRUE; // 数据头部验证有效标志位
|
||
reg.sd.len = 1; // 数据头部长度
|
||
reg.sd.pos = 0; // 数据头部偏移量
|
||
reg.sd.data[0] = FRAME_HEAD; // 数据头部数据
|
||
reg.ld.len = 2; // 数据长度
|
||
reg.ld.pos = 2; // 报文长度包含帧长,这里需要设置偏移2
|
||
reg.ld.valid = TRUE; // 数据长度有效标志位
|
||
reg.ld.little_endian = FALSE; // 数据长度是否小端模式
|
||
reg.argu.len_max = UART_RXSIZE; // 数据最大长度
|
||
reg.argu.len_min = 2; // 数据最小长度
|
||
reg.ed.valid = TRUE; // 数据尾部有效标志位
|
||
reg.ed.len = 1; // 数据尾部长度
|
||
reg.ed.data[0] = FRAME_TAIL; // 数据尾部数据
|
||
reg.echo_en = FALSE; // 是否回显
|
||
reg.func_ptr = data_analysis_event1; // 数据解析回调函数 data_analysis模块处理完数据后,会调用这个函数继续数据协议的处理
|
||
uart_data_analysis_cb = data_fsm_init(UART_DATA_ANALYSIS_PORT_1); // 注册数据处理函数 data_analysis模块会调用这个函数,将数据写入到data_analysis模块
|
||
data_reg(UART_DATA_ANALYSIS_PORT_1, reg); // 注册数据解析
|
||
}
|
||
|
||
/**
|
||
* @brief 需要识别帧头和没有帧尾的数据协议
|
||
* @return {*}
|
||
* @note
|
||
*/
|
||
static void data_register2(void)
|
||
{
|
||
/**
|
||
* 帧头 帧长度 源地址 目标地址 报文类型 报文体 校验
|
||
2 2 2 2 1 n 2
|
||
*/
|
||
#define FRAME_HEAD1 0xD5 // 帧头
|
||
#define FRAME_HEAD2 0xC8 // 帧尾
|
||
|
||
// 注册数据解析
|
||
data_reg_t reg;
|
||
reg.sd.valid = TRUE; // 数据头部验证有效标志位
|
||
reg.sd.len = 2; // 数据头部长度
|
||
reg.sd.pos = 0; // 数据头部偏移量
|
||
reg.sd.data[0] = FRAME_HEAD1; // 数据头部数据
|
||
reg.sd.data[1] = FRAME_HEAD2; // 数据头部数据
|
||
reg.ld.len = 2; // 数据长度
|
||
reg.ld.pos = 0; // 报文长度不包含帧长
|
||
reg.ld.valid = TRUE; // 数据长度有效标志位
|
||
reg.ld.little_endian = FALSE; // 数据长度是否小端模式
|
||
reg.argu.len_max = UART_RXSIZE; // 数据最大长度
|
||
reg.argu.len_min = 2; // 数据最小长度
|
||
reg.ed.valid = FALSE; // 数据尾部有效标志位
|
||
reg.echo_en = FALSE; // 是否回显
|
||
reg.func_ptr = data_analysis_event2; // 数据解析回调函数 data_analysis模块处理完数据后,会调用这个函数继续数据协议的处理
|
||
uart_data_analysis_cb = data_fsm_init(UART_DATA_ANALYSIS_PORT_2); // 注册数据处理函数 data_analysis模块会调用这个函数,将数据写入到data_analysis模块
|
||
data_reg(UART_DATA_ANALYSIS_PORT_2, reg); // 注册数据解析
|
||
}
|
||
|
||
int32_t main(void)
|
||
{
|
||
data_register1();
|
||
data_register2();
|
||
|
||
// 模拟串口数据
|
||
uint8_t data1[] = {0x05, 0x00, 0x0a, 0xff, 0xff, 0x00, 0x01, 0x00, 0x55, 0x40, 0x1b};
|
||
for (uint16_t i = 0; i < ARRAY_LEN(data1); i++)
|
||
{
|
||
uart_data_analysis_cb(UART_DATA_ANALYSIS_PORT_1, *(data1 + i));
|
||
}
|
||
|
||
// 模拟串口数据
|
||
uint8_t data2[] = {0xD5, 0xC8, 0x00, 0x07, 0xff, 0xff, 0x00, 0x01, 0x00, 0x55, 0x40};
|
||
for (uint16_t i = 0; i < ARRAY_LEN(data2); i++)
|
||
{
|
||
uart_data_analysis_cb(UART_DATA_ANALYSIS_PORT_2, *(data2 + i));
|
||
}
|
||
|
||
return 0;
|
||
}
|