#include #include #include #include #include "hx_serial.h" #include "hx_ringbuffer.h" #define FRAME_HEADER_1 0x55 #define FRAME_HEADER_2 0xAA #define MAX_DATA_LEN 232 #define CRC32_LEN 4 #define FRAME_HEADER_LEN 2 #define FRAME_SEQ_LEN 1 #define DATA_LEN_LEN 1 #define FRAME_OVERHEAD (FRAME_HEADER_LEN + FRAME_SEQ_LEN + DATA_LEN_LEN + CRC32_LEN) #define MAX_FRAME_LEN (FRAME_OVERHEAD + MAX_DATA_LEN) // CRC32 校验函数(假设已经实现) uint32_t crc32(const uint8_t *data, int len); // 解析一帧数据 int parse_frame(by_ringbuf_t *ringbuf, uint8_t *output_data, int *output_len) { uint8_t frame[MAX_FRAME_LEN]; int available_data = by_ringbuf_available_data(ringbuf); // printf("Available data: %d\n", available_data); // 检查是否有足够的数据解析一帧 if (available_data < FRAME_OVERHEAD) { return -1; // 数据不足,无法解析 }else{ // by_ringbuf_debug_print(ringbuf); } // 查找帧头 uint8_t header[2] = {FRAME_HEADER_1, FRAME_HEADER_2}; int header_pos = by_ringbuf_find(ringbuf, header, 2); printf("Header pos: %d\n", header_pos); if (header_pos < 0) { return -1; // 没有找到帧头 } // 弹出帧头之前的数据 by_ringbuf_pop(ringbuf, frame, header_pos); // 检查是否有足够的数据解析一帧 if (by_ringbuf_available_data(ringbuf) < MAX_FRAME_LEN) { return -1; // 数据不足,无法解析 } // 读取帧数据 by_ringbuf_pop(ringbuf, frame, MAX_FRAME_LEN); // 解析帧序号、有效数据长度、数据段和 CRC32 uint8_t seq = frame[FRAME_HEADER_LEN]; uint8_t valid_data_len = frame[FRAME_HEADER_LEN + FRAME_SEQ_LEN]; uint8_t *data_segment = &frame[FRAME_HEADER_LEN + FRAME_SEQ_LEN + DATA_LEN_LEN]; uint32_t received_crc = *(uint32_t *)&frame[FRAME_HEADER_LEN + FRAME_SEQ_LEN + DATA_LEN_LEN + MAX_DATA_LEN]; printf("Received frame: %d, valid_data_len: %d, received_crc: %08X\n", seq, valid_data_len, received_crc); // // 计算 CRC32 校验 // uint32_t calculated_crc = crc32(data_segment, valid_data_len); // if (received_crc != calculated_crc) { // return -1; // CRC 校验失败,丢弃该帧 // } // 将有效数据拼接到输出缓冲区 memcpy(&output_data[*output_len], data_segment, valid_data_len); *output_len += valid_data_len; // for(int i = 0; i < valid_data_len; i++){ // printf("0x%02X ", data_segment[i]); // } // 判断是否为最后一帧 if (valid_data_len < MAX_DATA_LEN) { return 1; // 最后一帧,解析完成 } return 0; // 成功解析一帧,但可能还有更多帧 } // 边读取边解析串口数据 int parse_serial_data(by_serial_t *serial_port, by_ringbuf_t *ringbuf, uint8_t *output_data, int *output_len) { uint8_t buffer[MAX_FRAME_LEN]; int ret; // 从串口读取数据到环形缓冲区 ret = by_serial_read(serial_port, buffer, MAX_FRAME_LEN); if (ret > 0) { by_ringbuf_append(ringbuf, buffer, ret); } // 尝试解析环形缓冲区中的数据 while (1) { int parse_result = parse_frame(ringbuf, output_data, output_len); if (parse_result == 1) { // printf("Parsed data length: %d\n", *output_len); return 0; // 解析完成 } else if (parse_result == -1) { // printf("Failed to parse frame\n"); break; // 数据不足或解析失败,退出循环 } } return -1; // 未找到完整帧 } // 示例 CRC32 校验函数(需要根据实际情况实现) uint32_t crc32(const uint8_t *data, int len) { // 这里实现 CRC32 校验算法 // 例如使用查表法或其他方法计算 CRC32 return 0; // 返回计算出的 CRC32 值 } int main() { by_serial_t serial_port; by_ringbuf_t ringbuf; uint8_t output_data[4096]; int output_len = 0; // 初始化串口和环形缓冲区 by_serial_init(&serial_port, "/dev/ttyUSB1"); by_ringbuf_init(&ringbuf, 4096); // 边读取边解析串口数据 while (1) { if (parse_serial_data(&serial_port, &ringbuf, output_data, &output_len) == 0) { printf("Parsed data length: %d\n", output_len); // 处理解析后的数据 break; // 解析完成,退出循环 } else { // printf("Waiting for more data...\n"); } usleep(1000); } // 释放资源 by_ringbuf_free(&ringbuf); return 0; }