141 lines
4.5 KiB
C
141 lines
4.5 KiB
C
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#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;
|
|
} |