diff --git a/serial_module.c b/serial_module.c index ccf7a56..5a37b79 100644 --- a/serial_module.c +++ b/serial_module.c @@ -1,6 +1,5 @@ #define PY_SSIZE_T_CLEAN #include -#include #include #include #include @@ -11,35 +10,34 @@ #include // 引入 pthread 库 // 宏定义 -// #define USE_FEC #ifdef USE_FEC #define FEC_SIZE 32 // 前向纠错冗余数据大小 #else #define FEC_SIZE 0 // 前向纠错冗余数据大小 #endif - #define FRAME_HEADER 0xAA55 // 帧头 +#define FRAME_TAIL 0x0D7E // 帧尾 #define FRAME_SIZE (240) // 每帧大小 #define HEADER_SIZE (4) // 帧头 + 帧序号 + 数据长度 +#define TAIL_SIZE (2) // 帧尾 #define CHECKSUM_SIZE (4) // CRC32 校验和大小(4 字节) -#define DATA_SIZE (FRAME_SIZE - HEADER_SIZE - CHECKSUM_SIZE - FEC_SIZE) // 数据段大小 +#define DATA_SIZE (FRAME_SIZE - HEADER_SIZE - CHECKSUM_SIZE - FEC_SIZE - TAIL_SIZE) // 数据段大小 #define RING_BUFFER_SIZE (1024 * 10) // 环形缓冲区大小 - default 10KB #define QUEUE_MAX_SIZE 1024 // 队列最大容量 // 全局变量 static by_serial_t serial_port; static by_ringbuf_t ring_buffer; -static uint8_t send_buffer[FRAME_SIZE]; -static uint8_t frame_counter = 0; -static uint8_t data_len = 0; - -uint8_t output_data[8192]; +static unsigned char send_buffer[FRAME_SIZE]; +static unsigned char frame_counter = 0; +static unsigned char data_len = 0; +unsigned char output_data[8192]; static int output_len = 0; // 定义队列结构体 typedef struct { - uint8_t *data; + unsigned char *data; int length; } FrameData; @@ -48,71 +46,82 @@ static FrameData frame_queue[QUEUE_MAX_SIZE]; // 存储接收 static int queue_head = 0; // 队列头指针 static int queue_tail = 0; // 队列尾指针 static pthread_mutex_t queue_mutex = PTHREAD_MUTEX_INITIALIZER; // 保护队列的互斥锁 -static bool stop_receiving = false; // 控制接收线程停止的标志 +static int stop_receiving = false; // 控制接收线程停止的标志 // 前向声明 void *receive_thread_func(void *arg); // 计算 CRC32 校验和 -uint32_t calculate_crc32(const uint8_t *data, size_t length) +unsigned long calculate_crc32(const unsigned char *data, size_t length) { return crc32(0, data, length); } // 解析一帧数据 -int parse_frame(by_ringbuf_t *ringbuf, uint8_t *output_data, int *output_len) +int parse_frame(by_ringbuf_t *ringbuf, unsigned char *output_data, int *output_len) { - uint8_t frame[FRAME_SIZE]; + unsigned char frame[FRAME_SIZE]; + unsigned char buffer[FRAME_SIZE * 3]; int available_data = by_ringbuf_available_data(ringbuf); - + while (by_ringbuf_available_data(ringbuf) < FRAME_SIZE) + { + int ret = by_serial_read(&serial_port, buffer, FRAME_SIZE); + if (ret > 0) + { + by_ringbuf_append(&ring_buffer, buffer, ret); + } + } + + // TODO 有无必要 // 检查是否有足够的数据解析一帧 - if (available_data < HEADER_SIZE + CHECKSUM_SIZE + FEC_SIZE) + if (available_data < FRAME_SIZE) { return -1; // 数据不足,无法解析 } - // 查找帧头 - uint16_t header = FRAME_HEADER; - int header_pos = by_ringbuf_find(ringbuf, (uint8_t *)&header, 2); + unsigned short header = FRAME_HEADER; + unsigned short tail = FRAME_TAIL; + int header_pos = by_ringbuf_find(ringbuf, (unsigned char *)&header, 2); if (header_pos < 0) { return -1; // 没有找到帧头 } - // 弹出帧头之前的数据 by_ringbuf_pop(ringbuf, frame, header_pos); - // 检查是否有足够的数据解析一帧 if (by_ringbuf_available_data(ringbuf) < FRAME_SIZE) { return -1; // 数据不足,无法解析 } - - // 读取帧数据 - by_ringbuf_pop(ringbuf, frame, FRAME_SIZE); - + // 读取帧数据 + by_ringbuf_pop(ringbuf, frame, HEADER_SIZE); + int tail_pos = by_ringbuf_find(ringbuf, (unsigned char *)&tail, 2); + if (tail_pos < FRAME_SIZE - HEADER_SIZE - TAIL_SIZE - 1) + { + printf(" fail, next frame header pos: %d\n", header_pos); + return -2; // 下一帧帧头小于 FRAME_SIZE,丢弃该帧 + } + else + { + by_ringbuf_pop(ringbuf, frame + HEADER_SIZE, tail_pos + TAIL_SIZE); + } // 解析帧序号、有效数据长度、数据段和 CRC32 - uint8_t seq = frame[2]; - uint8_t valid_data_len = frame[2 + 1]; - uint8_t *data_segment = &frame[2 + 1 + 1]; - uint32_t received_crc = *(uint32_t *)&frame[2 + 1 + 1 + DATA_SIZE]; - + unsigned char seq = frame[2]; + unsigned char valid_data_len = frame[2 + 1]; + unsigned char *data_segment = &frame[2 + 1 + 1]; + unsigned int received_crc = *(unsigned long *)&frame[HEADER_SIZE + DATA_SIZE]; // 计算 CRC32 校验 - uint32_t calculated_crc = calculate_crc32(frame, HEADER_SIZE + DATA_SIZE + FEC_SIZE); + unsigned int calculated_crc = calculate_crc32(frame, HEADER_SIZE + DATA_SIZE + FEC_SIZE); if (received_crc != calculated_crc) { printf("CRC mismatch! Expected: %08X, Received: %08X\n", calculated_crc, received_crc); - return -1; // CRC 校验失败,丢弃该帧 + return -2; // CRC 校验失败,丢弃该帧,严重错误 } - // 将有效数据拼接到输出缓冲区 memcpy(&output_data[*output_len], data_segment, valid_data_len); *output_len += valid_data_len; - printf("output len: %d\n", *output_len); - printf("Received frame: seq=%d, len=%d\r\n", seq, valid_data_len); - // 判断是否为最后一帧 if (valid_data_len < DATA_SIZE) { @@ -125,19 +134,8 @@ int parse_frame(by_ringbuf_t *ringbuf, uint8_t *output_data, int *output_len) // 接收线程函数 void *receive_thread_func(void *arg) { - while (!stop_receiving) { - - // 从串口读取数据到环形缓冲区 - uint8_t buffer[FRAME_SIZE]; - int ret = by_serial_read(&serial_port, buffer, FRAME_SIZE); - if (ret > 0) - { - by_ringbuf_append(&ring_buffer, buffer, ret); - } - - // 尝试解析环形缓冲区中的数据 while (1) { int parse_result = parse_frame(&ring_buffer, output_data, &output_len); @@ -166,12 +164,12 @@ void *receive_thread_func(void *arg) printf("Parsed data length: %d\n", output_len); break; // 数据不足或解析失败,退出循环 } - else if (parse_result == -1) + else if (parse_result == -2) { + output_len = 0; break; // 数据不足或解析失败,退出循环 } } - usleep(1000); // 避免占用过多 CPU } return NULL; @@ -185,20 +183,17 @@ static PyObject *serial_init(PyObject *self, PyObject *args) { return NULL; } - if (by_serial_init(&serial_port, dev_name) != 0) { PyErr_SetString(PyExc_IOError, "Failed to initialize serial port"); return NULL; } - // 初始化环形缓冲区 if (by_ringbuf_init(&ring_buffer, RING_BUFFER_SIZE) != 0) { PyErr_SetString(PyExc_IOError, "Failed to initialize ring buffer"); return NULL; } - // 启动接收线程 pthread_t receive_thread; stop_receiving = false; @@ -207,7 +202,6 @@ static PyObject *serial_init(PyObject *self, PyObject *args) PyErr_SetString(PyExc_RuntimeError, "Failed to start receive thread"); return NULL; } - Py_RETURN_NONE; } @@ -220,16 +214,13 @@ static PyObject *serial_send(PyObject *self, PyObject *args) { return NULL; } - size_t offset = 0; while (offset < length) { memset(send_buffer, 0, FRAME_SIZE); - // 构造帧头 - uint16_t header = FRAME_HEADER; + unsigned short header = FRAME_HEADER; memcpy(send_buffer, &header, 2); - // 构造帧序号和数据长度 memcpy(send_buffer + 2, &frame_counter, 1); if (length - offset > DATA_SIZE) @@ -241,28 +232,24 @@ static PyObject *serial_send(PyObject *self, PyObject *args) data_len = length - offset; } memcpy(send_buffer + 3, &data_len, 1); - // 拷贝该帧对应数据段 memcpy(send_buffer + HEADER_SIZE, data + offset, data_len); - printf("Received frame: seq=%d, len=%d\r\n", frame_counter, data_len); - // 计算 CRC32 校验和 - uint32_t crc = calculate_crc32(send_buffer, HEADER_SIZE + DATA_SIZE + FEC_SIZE); + unsigned long crc = calculate_crc32(send_buffer, HEADER_SIZE + DATA_SIZE + FEC_SIZE); memcpy(send_buffer + HEADER_SIZE + DATA_SIZE + FEC_SIZE, &crc, CHECKSUM_SIZE); - + unsigned short tail = FRAME_TAIL; + memcpy(send_buffer + HEADER_SIZE + DATA_SIZE + FEC_SIZE + CHECKSUM_SIZE, &tail, TAIL_SIZE); // 发送帧 if (by_serial_write(&serial_port, (const char *)send_buffer, FRAME_SIZE) != 0) { PyErr_SetString(PyExc_IOError, "Failed to send data over serial port"); return NULL; } - offset += DATA_SIZE; frame_counter++; usleep(80000); } - frame_counter = 0; Py_RETURN_NONE; } @@ -277,12 +264,10 @@ static PyObject *serial_receive(PyObject *self, PyObject *args) PyErr_SetString(PyExc_IOError, "No data available in the queue"); return NULL; } - // 获取队列中最早的数据包 FrameData frame = frame_queue[queue_head]; queue_head = (queue_head + 1) % QUEUE_MAX_SIZE; pthread_mutex_unlock(&queue_mutex); - // 返回解析后的数据 PyObject *result = Py_BuildValue("y#", frame.data, frame.length); free(frame.data); // 释放内存