Compare commits

..

2 Commits

Author SHA1 Message Date
c242c118f2 Merge branch 'master' of https://git.brisky.space/hexone2086/lora_plug 2025-02-19 20:00:14 +08:00
0d906284e1 update 2025-02-19 19:58:05 +08:00
4 changed files with 101 additions and 40 deletions

View File

@@ -17,6 +17,7 @@
#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);
@@ -209,7 +252,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;
} }
@@ -224,9 +268,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;
@@ -259,6 +305,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);
} }

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -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