串口2接收数据,comm处理信息

This commit is contained in:
sc committed 2025-10-20 23:23:35 +08:00
1 parent 7c463c07c6
commit 9f9c96d650
14 files changed
+861 -412

No files matched your search

+60
View File
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-10-20 Administrator the first version
*/
/* DATA_comm.c */
#include <rtthread.h>
#include "data_comm.h"
rt_mq_t proc_mq;
void proc_thread_entry(void *parameter)
{
struct proc_request *req;
while (1)
{
// 接收请求指针
if (rt_mq_recv(proc_mq, &req, sizeof(req), RT_WAITING_FOREVER) == RT_EOK)
{
if (!req) continue;
rt_kprintf("Processing: %.*s\n", req->input_len, req->input);
// 示例处理:回显
req->output_len = rt_snprintf(req->output, sizeof(req->output),
"Echo: %.*s", req->input_len, req->input);
// 通知 UART 线程可以发送了
if (req->sem)
{
rt_sem_release(req->sem);
}
}
}
}
int data_comm_init(void)
{
proc_mq = rt_mq_create("proc_mq", sizeof(struct proc_request*), 5, RT_IPC_FLAG_FIFO);
if (proc_mq == RT_NULL)
{
rt_kprintf("Failed to create message queue!\n");
return -1;
}
rt_thread_t tid = rt_thread_create("proc", proc_thread_entry, RT_NULL,
2048, 20, 10);
if (tid != RT_NULL)
{
rt_thread_startup(tid);
}
return 0;
}
//INIT_COMPONENT_EXPORT(data_comm_init);
+31
View File
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-10-20 Administrator the first version
*/
#ifndef APPLICATIONS_DATA_COMM_H_
#define APPLICATIONS_DATA_COMM_H_
// 最大输入/输出长度
#define MAX_INPUT_LEN 512
#define MAX_OUTPUT_LEN 1024
// 请求结构体
struct proc_request {
char input[MAX_INPUT_LEN];
int input_len;
char output[MAX_OUTPUT_LEN];
int output_len;
struct rt_semaphore *sem; // 指向动态分配的信号量
};
// 消息队列(供外部使用)
extern rt_mq_t proc_mq;
int data_comm_init(void);
#endif /* APPLICATIONS_DATA_COMM_H_ */
+151
View File
@@ -0,0 +1,151 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-10-20 Administrator the first version
*/
/* DATA_uart.c */
#include <rtthread.h>
#include <rtdevice.h>
#include "data_comm.h"
#define SAMPLE_UART_NAME "uart2"
#define DMA_RX_BUF_SIZE 512
#define RINGBUF_SIZE 4096
static rt_device_t serial;
// DMA 接收缓冲区
static rt_uint8_t dma_rx_buffer[DMA_RX_BUF_SIZE];
// 环形缓冲区(暂存未完整报文)
static struct rt_ringbuffer rx_rb;
static rt_uint8_t rb_pool[RINGBUF_SIZE];
// 接收回调信号量
static struct rt_semaphore rx_sem;
// 函数声明
static rt_err_t uart_rx_ind(rt_device_t dev, rt_size_t size);
static int get_line(char *buf, int maxlen);
void uart_thread_entry(void *parameter)
{
char input[MAX_INPUT_LEN];
int len;
// 初始化环形缓冲区和信号量
rt_ringbuffer_init(&rx_rb, rb_pool, sizeof(rb_pool));
rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
// 查找串口设备
serial = rt_device_find(SAMPLE_UART_NAME);
if (!serial) {
rt_kprintf("Cannot find %s\n", SAMPLE_UART_NAME);
return;
}
// 配置串口参数(只设置 bufsz,去掉 dma_rx)
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
config.bufsz = DMA_RX_BUF_SIZE; // 设置接收缓冲区大小
rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, &config);
// 打开设备:关键!使用 RT_DEVICE_FLAG_DMA_RX 启用 DMA 接收
rt_err_t result = rt_device_open(serial, RT_DEVICE_FLAG_DMA_RX | RT_DEVICE_FLAG_DMA_TX);
if (result != RT_EOK)
{
rt_kprintf("Failed to open %s with DMA, error=%d\n", SAMPLE_UART_NAME, result);
return;
}
// 设置接收指示回调(DMA 完成或中断后调用)
rt_device_set_rx_indicate(serial, uart_rx_ind);
rt_kprintf("UART DMA thread running...\n");
while (1)
{
// 等待数据就绪
if (rt_sem_take(&rx_sem, RT_WAITING_FOREVER) == RT_EOK)
{
// 处理接收到的数据(提取完整行)
while ((len = get_line(input, sizeof(input))) > 0)
{
rt_kprintf("Received: %.*s\n", len, input);
// 动态分配请求结构体(见之前完整代码)
struct proc_request *req = rt_malloc(sizeof(struct proc_request));
if (!req) continue;
rt_strncpy(req->input, input, sizeof(req->input));
req->input_len = len;
req->sem = rt_malloc(sizeof(struct rt_semaphore));
if (!req->sem) {
rt_free(req);
continue;
}
rt_sem_init(req->sem, "uart_resp", 0, RT_IPC_FLAG_FIFO);
// 发送到处理线程
if (rt_mq_send(proc_mq, &req, sizeof(req)) == RT_EOK)
{
// 等待处理完成
if (rt_sem_take(req->sem, RT_WAITING_FOREVER) == RT_EOK)
{
rt_device_write(serial, 0, req->output, req->output_len);
}
}
// 清理
rt_sem_detach(req->sem); // 或 rt_sem_delete
rt_free(req->sem);
rt_free(req);
}
}
}
}
// DMA 接收回调
static rt_err_t uart_rx_ind(rt_device_t dev, rt_size_t size)
{
rt_ringbuffer_put(&rx_rb, (const rt_uint8_t*)dma_rx_buffer, size);
rt_sem_release(&rx_sem); // 通知线程处理
return RT_EOK;
}
// 从环形缓冲区提取一行
static int get_line(char *buf, int maxlen)
{
int i = 0;
char ch;
while (rt_ringbuffer_getchar(&rx_rb, &ch) == 1)
{
if (ch == '\n' || ch == '\r') {
if (i > 0) break;
continue;
}
if (i < maxlen - 1) buf[i++] = ch;
}
buf[i] = '\0';
return i > 0 ? i : 0;
}
// 启动 UART 线程
int start_uart_thread(void)
{
rt_thread_t tid = rt_thread_create("uart_rx", uart_thread_entry, RT_NULL,
4096, // 栈大小:4KB
25, // 优先级
10); // 时间片
if (tid != RT_NULL)
{
rt_thread_startup(tid);
}
return 0;
}
//INIT_COMPONENT_EXPORT(start_uart_thread);
+15
View File
@@ -0,0 +1,15 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-10-20 Administrator the first version
*/
#ifndef APPLICATIONS_DATA_UART_H_
#define APPLICATIONS_DATA_UART_H_
int start_uart_thread(void);
#endif /* APPLICATIONS_DATA_UART_H_ */