update
This commit is contained in:
113
serial_module.c
113
serial_module.c
@@ -11,12 +11,13 @@
|
|||||||
#include <pthread.h> // 引入 pthread 库
|
#include <pthread.h> // 引入 pthread 库
|
||||||
|
|
||||||
// 宏定义
|
// 宏定义
|
||||||
#define USE_FEC
|
// #define USE_FEC
|
||||||
#ifdef USE_FEC
|
#ifdef USE_FEC
|
||||||
#define FEC_SIZE 32 // 前向纠错冗余数据大小
|
#define FEC_SIZE 32 // 前向纠错冗余数据大小
|
||||||
#else
|
#else
|
||||||
#define FEC_SIZE 0 // 前向纠错冗余数据大小
|
#define FEC_SIZE 0 // 前向纠错冗余数据大小
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define FRAME_HEADER 0xAA55 // 帧头
|
#define FRAME_HEADER 0xAA55 // 帧头
|
||||||
#define FRAME_SIZE (240) // 每帧大小
|
#define FRAME_SIZE (240) // 每帧大小
|
||||||
#define HEADER_SIZE (4) // 帧头 + 帧序号 + 数据长度
|
#define HEADER_SIZE (4) // 帧头 + 帧序号 + 数据长度
|
||||||
@@ -32,8 +33,12 @@ static uint8_t send_buffer[FRAME_SIZE];
|
|||||||
static uint8_t frame_counter = 0;
|
static uint8_t frame_counter = 0;
|
||||||
static uint8_t data_len = 0;
|
static uint8_t data_len = 0;
|
||||||
|
|
||||||
|
uint8_t output_data[8192];
|
||||||
|
static int output_len = 0;
|
||||||
|
|
||||||
// 定义队列结构体
|
// 定义队列结构体
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
int length;
|
int length;
|
||||||
} FrameData;
|
} FrameData;
|
||||||
@@ -49,24 +54,28 @@ static bool stop_receiving = false; // 控制接收线程停止的标
|
|||||||
void *receive_thread_func(void *arg);
|
void *receive_thread_func(void *arg);
|
||||||
|
|
||||||
// 计算 CRC32 校验和
|
// 计算 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);
|
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];
|
uint8_t frame[FRAME_SIZE];
|
||||||
int available_data = by_ringbuf_available_data(ringbuf);
|
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; // 数据不足,无法解析
|
return -1; // 数据不足,无法解析
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查找帧头
|
// 查找帧头
|
||||||
uint16_t header = FRAME_HEADER;
|
uint16_t header = FRAME_HEADER;
|
||||||
int header_pos = by_ringbuf_find(ringbuf, (uint8_t *)&header, 2);
|
int header_pos = by_ringbuf_find(ringbuf, (uint8_t *)&header, 2);
|
||||||
if (header_pos < 0) {
|
if (header_pos < 0)
|
||||||
|
{
|
||||||
return -1; // 没有找到帧头
|
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);
|
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; // 数据不足,无法解析
|
return -1; // 数据不足,无法解析
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,7 +99,8 @@ int parse_frame(by_ringbuf_t *ringbuf, uint8_t *output_data, int *output_len) {
|
|||||||
|
|
||||||
// 计算 CRC32 校验
|
// 计算 CRC32 校验
|
||||||
uint32_t calculated_crc = calculate_crc32(frame, HEADER_SIZE + DATA_SIZE + FEC_SIZE);
|
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);
|
printf("CRC mismatch! Expected: %08X, Received: %08X\n", calculated_crc, received_crc);
|
||||||
return -1; // 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);
|
memcpy(&output_data[*output_len], data_segment, valid_data_len);
|
||||||
*output_len += 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");
|
printf("Received last frame!\n");
|
||||||
return 1; // 最后一帧,解析完成
|
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) {
|
void *receive_thread_func(void *arg)
|
||||||
while (!stop_receiving) {
|
{
|
||||||
uint8_t output_data[8192];
|
|
||||||
int output_len = 0;
|
while (!stop_receiving)
|
||||||
|
{
|
||||||
|
|
||||||
// 从串口读取数据到环形缓冲区
|
// 从串口读取数据到环形缓冲区
|
||||||
uint8_t buffer[FRAME_SIZE];
|
uint8_t buffer[FRAME_SIZE];
|
||||||
int ret = by_serial_read(&serial_port, 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);
|
by_ringbuf_append(&ring_buffer, buffer, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 尝试解析环形缓冲区中的数据
|
// 尝试解析环形缓冲区中的数据
|
||||||
while (1) {
|
while (1)
|
||||||
|
{
|
||||||
int parse_result = parse_frame(&ring_buffer, output_data, &output_len);
|
int parse_result = parse_frame(&ring_buffer, output_data, &output_len);
|
||||||
if (parse_result == 1) {
|
if (parse_result == 1)
|
||||||
|
{
|
||||||
// 将解析后的数据放入队列
|
// 将解析后的数据放入队列
|
||||||
pthread_mutex_lock(&queue_mutex);
|
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);
|
frame_queue[queue_tail].data = malloc(output_len);
|
||||||
memcpy(frame_queue[queue_tail].data, output_data, 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;
|
frame_queue[queue_tail].length = output_len;
|
||||||
queue_tail = (queue_tail + 1) % QUEUE_MAX_SIZE;
|
queue_tail = (queue_tail + 1) % QUEUE_MAX_SIZE;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
printf("Queue is full, dropping frame!\n");
|
printf("Queue is full, dropping frame!\n");
|
||||||
}
|
}
|
||||||
|
output_len = 0;
|
||||||
pthread_mutex_unlock(&queue_mutex);
|
pthread_mutex_unlock(&queue_mutex);
|
||||||
break;
|
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; // 数据不足或解析失败,退出循环
|
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;
|
const char *dev_name;
|
||||||
if (!PyArg_ParseTuple(args, "s", &dev_name)) {
|
if (!PyArg_ParseTuple(args, "s", &dev_name))
|
||||||
|
{
|
||||||
return NULL;
|
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");
|
PyErr_SetString(PyExc_IOError, "Failed to initialize serial port");
|
||||||
return NULL;
|
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");
|
PyErr_SetString(PyExc_IOError, "Failed to initialize ring buffer");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -166,7 +202,8 @@ static PyObject *serial_init(PyObject *self, PyObject *args) {
|
|||||||
// 启动接收线程
|
// 启动接收线程
|
||||||
pthread_t receive_thread;
|
pthread_t receive_thread;
|
||||||
stop_receiving = false;
|
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");
|
PyErr_SetString(PyExc_RuntimeError, "Failed to start receive thread");
|
||||||
return NULL;
|
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;
|
const char *data;
|
||||||
Py_ssize_t length;
|
Py_ssize_t length;
|
||||||
if (!PyArg_ParseTuple(args, "s#", &data, &length)) {
|
if (!PyArg_ParseTuple(args, "s#", &data, &length))
|
||||||
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
while (offset < length) {
|
while (offset < length)
|
||||||
|
{
|
||||||
memset(send_buffer, 0, FRAME_SIZE);
|
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);
|
memcpy(send_buffer + 2, &frame_counter, 1);
|
||||||
if (length - offset > DATA_SIZE) {
|
if (length - offset > DATA_SIZE)
|
||||||
|
{
|
||||||
data_len = DATA_SIZE;
|
data_len = DATA_SIZE;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
data_len = length - offset;
|
data_len = length - offset;
|
||||||
}
|
}
|
||||||
memcpy(send_buffer + 3, &data_len, 1);
|
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);
|
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");
|
PyErr_SetString(PyExc_IOError, "Failed to send data over serial port");
|
||||||
return NULL;
|
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);
|
pthread_mutex_lock(&queue_mutex);
|
||||||
if (queue_head == queue_tail) {
|
if (queue_head == queue_tail)
|
||||||
|
{
|
||||||
pthread_mutex_unlock(&queue_mutex);
|
pthread_mutex_unlock(&queue_mutex);
|
||||||
PyErr_SetString(PyExc_IOError, "No data available in the queue");
|
PyErr_SetString(PyExc_IOError, "No data available in the queue");
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -257,6 +303,7 @@ static struct PyModuleDef serialmodule = {
|
|||||||
SerialMethods};
|
SerialMethods};
|
||||||
|
|
||||||
// 模块初始化函数
|
// 模块初始化函数
|
||||||
PyMODINIT_FUNC PyInit_serial_module(void) {
|
PyMODINIT_FUNC PyInit_serial_module(void)
|
||||||
|
{
|
||||||
return PyModule_Create(&serialmodule);
|
return PyModule_Create(&serialmodule);
|
||||||
}
|
}
|
||||||
BIN
serial_module.so
BIN
serial_module.so
Binary file not shown.
BIN
test_recv.jpg
BIN
test_recv.jpg
Binary file not shown.
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 14 KiB |
20
test_recv.py
20
test_recv.py
@@ -1,21 +1,35 @@
|
|||||||
import serial_module
|
import serial_module
|
||||||
import cv2
|
import cv2
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
import time
|
||||||
|
|
||||||
serial_module.init("/dev/ttyUSB1")
|
serial_module.init("/dev/ttyUSB0")
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
|
# time.sleep(1);
|
||||||
data = serial_module.receive()
|
data = serial_module.receive()
|
||||||
|
if data == None:
|
||||||
|
continue
|
||||||
# print("Received data:", data)
|
# print("Received data:", data)
|
||||||
if data:
|
if data:
|
||||||
|
print(f"size of data: {len(data)}")
|
||||||
frame = np.frombuffer(data, np.uint8)
|
frame = np.frombuffer(data, np.uint8)
|
||||||
# 将数据转换为图像
|
# 将数据转换为图像
|
||||||
|
print(2)
|
||||||
image = cv2.imdecode(frame, cv2.IMREAD_COLOR)
|
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)
|
cv2.imwrite('test_recv.jpg', image)
|
||||||
|
print(5)
|
||||||
# 等待按键输入
|
# 等待按键输入
|
||||||
if cv2.waitKey(1) & 0xFF == ord('q'):
|
if cv2.waitKey(1) & 0xFF == ord('q'):
|
||||||
break
|
break
|
||||||
|
pass
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("Error:", e)
|
# print("Error:", e)
|
||||||
|
pass
|
||||||
Reference in New Issue
Block a user