diff --git a/serial_module.c b/serial_module.c index eb92914..9afbb19 100644 --- a/serial_module.c +++ b/serial_module.c @@ -11,12 +11,13 @@ #include // 引入 pthread 库 // 宏定义 -#define USE_FEC +// #define USE_FEC #ifdef USE_FEC #define FEC_SIZE 32 // 前向纠错冗余数据大小 #else #define FEC_SIZE 0 // 前向纠错冗余数据大小 #endif + #define FRAME_HEADER 0xAA55 // 帧头 #define FRAME_SIZE (240) // 每帧大小 #define HEADER_SIZE (4) // 帧头 + 帧序号 + 数据长度 @@ -32,41 +33,49 @@ 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 int output_len = 0; + // 定义队列结构体 -typedef struct { +typedef struct +{ uint8_t *data; int length; } FrameData; // 队列相关定义 -static FrameData frame_queue[QUEUE_MAX_SIZE]; // 存储接收到的数据帧 -static int queue_head = 0; // 队列头指针 -static int queue_tail = 0; // 队列尾指针 +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 bool stop_receiving = false; // 控制接收线程停止的标志 // 前向声明 void *receive_thread_func(void *arg); // 计算 CRC32 校验和 -uint32_t calculate_crc32(const uint8_t *data, size_t length) { +uint32_t calculate_crc32(const uint8_t *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, uint8_t *output_data, int *output_len) +{ uint8_t frame[FRAME_SIZE]; int available_data = by_ringbuf_available_data(ringbuf); - + // 检查是否有足够的数据解析一帧 - if (available_data < HEADER_SIZE + CHECKSUM_SIZE + FEC_SIZE) { + if (available_data < HEADER_SIZE + CHECKSUM_SIZE + FEC_SIZE) + { return -1; // 数据不足,无法解析 } // 查找帧头 uint16_t header = FRAME_HEADER; int header_pos = by_ringbuf_find(ringbuf, (uint8_t *)&header, 2); - if (header_pos < 0) { + if (header_pos < 0) + { return -1; // 没有找到帧头 } @@ -74,7 +83,8 @@ int parse_frame(by_ringbuf_t *ringbuf, uint8_t *output_data, int *output_len) { by_ringbuf_pop(ringbuf, frame, header_pos); // 检查是否有足够的数据解析一帧 - if (by_ringbuf_available_data(ringbuf) < FRAME_SIZE) { + if (by_ringbuf_available_data(ringbuf) < FRAME_SIZE) + { return -1; // 数据不足,无法解析 } @@ -89,7 +99,8 @@ int parse_frame(by_ringbuf_t *ringbuf, uint8_t *output_data, int *output_len) { // 计算 CRC32 校验 uint32_t calculated_crc = calculate_crc32(frame, HEADER_SIZE + DATA_SIZE + FEC_SIZE); - if (received_crc != calculated_crc) { + if (received_crc != calculated_crc) + { printf("CRC mismatch! Expected: %08X, Received: %08X\n", calculated_crc, received_crc); return -1; // CRC 校验失败,丢弃该帧 } @@ -98,8 +109,13 @@ int parse_frame(by_ringbuf_t *ringbuf, uint8_t *output_data, int *output_len) { 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) { + if (valid_data_len < DATA_SIZE) + { printf("Received last frame!\n"); return 1; // 最后一帧,解析完成 } @@ -107,35 +123,51 @@ 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 output_data[8192]; - int output_len = 0; +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) { + if (ret > 0) + { by_ringbuf_append(&ring_buffer, buffer, ret); } // 尝试解析环形缓冲区中的数据 - while (1) { + while (1) + { int parse_result = parse_frame(&ring_buffer, output_data, &output_len); - if (parse_result == 1) { + if (parse_result == 1) + { // 将解析后的数据放入队列 pthread_mutex_lock(&queue_mutex); - if ((queue_tail + 1) % QUEUE_MAX_SIZE != queue_head) { // 队列未满 + if ((queue_tail + 1) % QUEUE_MAX_SIZE != queue_head) + { // 队列未满 frame_queue[queue_tail].data = malloc(output_len); memcpy(frame_queue[queue_tail].data, output_data, output_len); + printf("output_len2: %d\n", output_len); frame_queue[queue_tail].length = output_len; queue_tail = (queue_tail + 1) % QUEUE_MAX_SIZE; - } else { + } + else + { printf("Queue is full, dropping frame!\n"); } + output_len = 0; pthread_mutex_unlock(&queue_mutex); break; - } else if (parse_result == -1) { + } + else if (parse_result == 0) + { + printf("Parsed data length: %d\n", output_len); + break; // 数据不足或解析失败,退出循环 + } + else if (parse_result == -1) + { break; // 数据不足或解析失败,退出循环 } } @@ -146,19 +178,23 @@ void *receive_thread_func(void *arg) { } // 初始化串口 -static PyObject *serial_init(PyObject *self, PyObject *args) { +static PyObject *serial_init(PyObject *self, PyObject *args) +{ const char *dev_name; - if (!PyArg_ParseTuple(args, "s", &dev_name)) { + if (!PyArg_ParseTuple(args, "s", &dev_name)) + { return NULL; } - if (by_serial_init(&serial_port, dev_name) != 0) { + 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) { + if (by_ringbuf_init(&ring_buffer, RING_BUFFER_SIZE) != 0) + { PyErr_SetString(PyExc_IOError, "Failed to initialize ring buffer"); return NULL; } @@ -166,7 +202,8 @@ static PyObject *serial_init(PyObject *self, PyObject *args) { // 启动接收线程 pthread_t receive_thread; stop_receiving = false; - if (pthread_create(&receive_thread, NULL, receive_thread_func, NULL) != 0) { + if (pthread_create(&receive_thread, NULL, receive_thread_func, NULL) != 0) + { PyErr_SetString(PyExc_RuntimeError, "Failed to start receive thread"); return NULL; } @@ -175,15 +212,18 @@ static PyObject *serial_init(PyObject *self, PyObject *args) { } // 发送数据 -static PyObject *serial_send(PyObject *self, PyObject *args) { +static PyObject *serial_send(PyObject *self, PyObject *args) +{ const char *data; Py_ssize_t length; - if (!PyArg_ParseTuple(args, "s#", &data, &length)) { + if (!PyArg_ParseTuple(args, "s#", &data, &length)) + { return NULL; } size_t offset = 0; - while (offset < length) { + while (offset < length) + { memset(send_buffer, 0, FRAME_SIZE); // 构造帧头 @@ -192,9 +232,12 @@ static PyObject *serial_send(PyObject *self, PyObject *args) { // 构造帧序号和数据长度 memcpy(send_buffer + 2, &frame_counter, 1); - if (length - offset > DATA_SIZE) { + if (length - offset > DATA_SIZE) + { data_len = DATA_SIZE; - } else { + } + else + { data_len = length - offset; } memcpy(send_buffer + 3, &data_len, 1); @@ -207,7 +250,8 @@ static PyObject *serial_send(PyObject *self, PyObject *args) { memcpy(send_buffer + HEADER_SIZE + DATA_SIZE + FEC_SIZE, &crc, CHECKSUM_SIZE); // 发送帧 - if (by_serial_write(&serial_port, (const char *)send_buffer, FRAME_SIZE) != 0) { + 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; } @@ -222,9 +266,11 @@ static PyObject *serial_send(PyObject *self, PyObject *args) { } // 接收数据 -static PyObject *serial_receive(PyObject *self, PyObject *args) { +static PyObject *serial_receive(PyObject *self, PyObject *args) +{ pthread_mutex_lock(&queue_mutex); - if (queue_head == queue_tail) { + if (queue_head == queue_tail) + { pthread_mutex_unlock(&queue_mutex); PyErr_SetString(PyExc_IOError, "No data available in the queue"); return NULL; @@ -257,6 +303,7 @@ static struct PyModuleDef serialmodule = { SerialMethods}; // 模块初始化函数 -PyMODINIT_FUNC PyInit_serial_module(void) { +PyMODINIT_FUNC PyInit_serial_module(void) +{ return PyModule_Create(&serialmodule); } \ No newline at end of file diff --git a/serial_module.so b/serial_module.so index 6a5dec9..c3989dd 100755 Binary files a/serial_module.so and b/serial_module.so differ diff --git a/test_recv.jpg b/test_recv.jpg index 5dcabf5..bc7115a 100644 Binary files a/test_recv.jpg and b/test_recv.jpg differ diff --git a/test_recv.py b/test_recv.py index 6ef147c..ce09cea 100644 --- a/test_recv.py +++ b/test_recv.py @@ -1,21 +1,35 @@ import serial_module import cv2 import numpy as np +import time -serial_module.init("/dev/ttyUSB1") +serial_module.init("/dev/ttyUSB0") while True: try: + # time.sleep(1); data = serial_module.receive() + if data == None: + continue # print("Received data:", data) if data: + print(f"size of data: {len(data)}") frame = np.frombuffer(data, np.uint8) # 将数据转换为图像 + print(2) image = cv2.imdecode(frame, cv2.IMREAD_COLOR) + + print(f"Image shape: {image.shape}") + + print(3) # 显示图像 - cv2.imshow('Received Image', image) + # cv2.imshow('Received Image', image) + # print(4) cv2.imwrite('test_recv.jpg', image) + print(5) # 等待按键输入 if cv2.waitKey(1) & 0xFF == ord('q'): break + pass except Exception as e: - print("Error:", e) \ No newline at end of file + # print("Error:", e) + pass \ No newline at end of file