串口2接收数据,comm处理信息
This commit is contained in:
1 parent
7c463c07c6
commit
9f9c96d650
14 files changed
+861
-412
No files matched your search
@@ -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);
|
||||
@@ -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_ */
|
||||
@@ -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);
|
||||
@@ -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_ */
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
#include <board.h>
|
||||
#include "DB_SQLite.h"
|
||||
|
||||
#include <dbhelper.h>
|
||||
#define DB_NAME "/rt.db"
|
||||
|
||||
void db_sqlite(void *parameter)
|
||||
{
|
||||
int db_HelperInit;
|
||||
int db_;
|
||||
|
||||
db_HelperInit = db_helper_init();
|
||||
|
||||
if(db_HelperInit =RT_EOK){
|
||||
rt_kprintf("HelperInit database\n");
|
||||
}else {
|
||||
// db_ = db_create_database("CREATE TABLE student(id INTEGER PRIMARY KEY AUTOINCREMENT,name varchar(32) NOT NULL,score INT NOT NULL);");
|
||||
// if(db_=0){rt_kprintf("database ok\n");}else{rt_kprintf("database no\n");}
|
||||
}
|
||||
|
||||
/* int fd = 0;
|
||||
const char *dbname = db_get_name();
|
||||
fd = open(dbname, O_RDONLY);
|
||||
if (fd > 0)
|
||||
rt_kprintf("%s exist\r\n", dbname);
|
||||
else
|
||||
rt_kprintf("%s not exist\r\n");
|
||||
|
||||
|
||||
const char *sql = "CREATE TABLE IF NOT EXISTS student(id INTEGER PRIMARY KEY AUTOINCREMENT,name varchar(32) NOT NULL,score INT NOT NULL);";
|
||||
rt_kprintf("sql cmd: %s\r\n\r\n", sql);
|
||||
int ret = db_create_database(sql);
|
||||
rt_kprintf("sql ret: %d\r\n", ret);*/
|
||||
|
||||
// sqlite3_os_init();
|
||||
|
||||
/* int rc = db_connect("/rt.db");
|
||||
if (rc <0) {
|
||||
const char *sql = "CREATE TABLE student(id INTEGER PRIMARY KEY AUTOINCREMENT,name varchar(32) NOT NULL,score INT NOT NULL);";
|
||||
int db_create_database(sql);
|
||||
}*/
|
||||
}
|
||||
|
||||
/* 线程 */
|
||||
void thread_DB_SQLite(void)
|
||||
{
|
||||
/* 初始化线程 1,名称是 thread1,入口是 thread1_entry*/
|
||||
rt_thread_t tid;
|
||||
tid = rt_thread_create("db_sqlite", db_sqlite, RT_NULL, 1024*32, 3, 10);
|
||||
|
||||
if (tid != RT_NULL)
|
||||
{
|
||||
rt_thread_startup(tid);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_kprintf("Failed to create sqlite_sys thread!\n");
|
||||
}
|
||||
// return 0;
|
||||
}
|
||||
@@ -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_DB_DB_SQLITE_H_
|
||||
#define APPLICATIONS_DB_SQLITE_SYS_H_
|
||||
|
||||
void thread_DB_SQLite(void);
|
||||
|
||||
#endif /* APPLICATIONS_DB_DB_SQLITE_H_ */
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <rtdevice.h>
|
||||
#include <board.h>
|
||||
#include"drv_common.h"
|
||||
#include "RUN_LED.h"
|
||||
|
||||
#define LED_PIN GET_PIN(C,13)
|
||||
|
||||
@@ -18,12 +19,12 @@ void RUN_LED(void *parameter)
|
||||
}
|
||||
}
|
||||
|
||||
/* 线程示例 */
|
||||
/* 线程 */
|
||||
void thread_RUN_LED(void)
|
||||
{
|
||||
/* 初始化线程 1,名称是 thread1,入口是 thread1_entry*/
|
||||
rt_thread_t tid;
|
||||
tid = rt_thread_create("run_led", RUN_LED, RT_NULL, 512, 3, 10);
|
||||
tid = rt_thread_create("run_led", RUN_LED, RT_NULL, 256, 3, 10);
|
||||
|
||||
if (tid != RT_NULL)
|
||||
{
|
||||
|
||||
+9
-45
@@ -1,4 +1,6 @@
|
||||
/*
|
||||
#include <DBSQL/DB_SQLite.h>
|
||||
#include <DB_SQLite.h>
|
||||
* Copyright (c) 2006-2025, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
@@ -12,61 +14,23 @@
|
||||
#include "dfs_fs.h"
|
||||
#include <rtdbg.h>
|
||||
#include "RUN_LED.h"
|
||||
|
||||
#include <dbhelper.h>
|
||||
#define DB_NAME "/rt.db"
|
||||
#include "DB_SQLite.h"
|
||||
|
||||
#define DBG_TAG "main"
|
||||
#define DBG_LVL DBG_LOG
|
||||
#include <rtdbg.h>
|
||||
|
||||
|
||||
extern rt_sem_t mount_sem; // 引用上面SD挂载线程定义的信号量
|
||||
|
||||
int main(void)
|
||||
{
|
||||
rt_thread_mdelay(100); //等待sd_mount线程挂载文件系统,可使用IPC信号量完成同步,提高实时性
|
||||
rt_sem_take(mount_sem, rt_tick_from_millisecond(5000)); // 等待挂载完成,最多等待 5 秒
|
||||
thread_RUN_LED();//运行指示灯线程
|
||||
thread_DB_SQLite();
|
||||
|
||||
thread_RUN_LED();
|
||||
|
||||
//int db_HelperInit;
|
||||
// db_HelperInit = db_helper_init();
|
||||
|
||||
// if(db_HelperInit =RT_EOK){
|
||||
// rt_kprintf("HelperInit database\n");
|
||||
// }
|
||||
start_uart_thread();
|
||||
data_comm_init();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// int db_helper_init();
|
||||
|
||||
// sqlite3 *db;
|
||||
// int8_t rc;
|
||||
|
||||
// rc = sqlite3_open("rt.db", &db);
|
||||
// if (rc != SQLITE_OK)
|
||||
// {
|
||||
//rt_kprintf("Cannot open database: %s\n", sqlite3_errmsg(db));
|
||||
//return -1;
|
||||
// }else{
|
||||
// rt_kprintf("Database opened successfully\n");
|
||||
// sqlite3_close(db);
|
||||
// }
|
||||
// sqlite3_os_init();
|
||||
//if(int sqlite3_os_init()==RT_EOK){LOG_D("Sqlite int RT_EOK!");}
|
||||
|
||||
|
||||
// sqlite3_os_init();
|
||||
|
||||
/* int rc = db_connect("/rt.db");
|
||||
if (rc <0) {
|
||||
const char *sql = "CREATE TABLE student(id INTEGER PRIMARY KEY AUTOINCREMENT,name varchar(32) NOT NULL,score INT NOT NULL);";
|
||||
int db_create_database(sql);
|
||||
}*/
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
@@ -15,42 +15,81 @@
|
||||
#define DBG_LVL DBG_LOG
|
||||
#include <rtdbg.h>
|
||||
|
||||
|
||||
rt_sem_t mount_sem = RT_NULL;
|
||||
|
||||
void sd_mount(void *parameter)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
LOG_I("SD mount thread started, waiting for SD card...");
|
||||
int retry = 0;
|
||||
while (retry<10)
|
||||
{
|
||||
if (rt_device_find("sd0") != RT_NULL)
|
||||
{
|
||||
if (dfs_mount("sd0", "/", "elm", 0, 0) == RT_EOK)
|
||||
{
|
||||
LOG_I("SD card mounted to '/' successfully");
|
||||
// 挂载成功,释放信号量
|
||||
if (mount_sem != RT_NULL)
|
||||
{
|
||||
rt_sem_release(mount_sem);
|
||||
}
|
||||
break; // 退出线程循环
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_W("SD card mount failed, retrying...");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_D("SD device 'sd0' not found, retrying...");
|
||||
}
|
||||
|
||||
if(rt_device_find("sd0") != RT_NULL)
|
||||
{
|
||||
if (dfs_mount("sd0", "/", "elm", 0, 0) == RT_EOK)
|
||||
{
|
||||
LOG_I("sd card mount to '/fatfs'");
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_W("sd card mount to '/fatfs' failed!");
|
||||
}
|
||||
}
|
||||
}
|
||||
// 避免空转,延时 100ms 再试
|
||||
rt_thread_mdelay(500);
|
||||
retry++;
|
||||
}
|
||||
}
|
||||
|
||||
int stm32_sdcard_mount(void)
|
||||
{
|
||||
rt_thread_t tid;
|
||||
|
||||
tid = rt_thread_create("sd_mount", sd_mount, RT_NULL,
|
||||
1024*4, RT_THREAD_PRIORITY_MAX - 2, 20);
|
||||
if (tid != RT_NULL)
|
||||
{
|
||||
rt_thread_startup(tid);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("create sd_mount thread err!");
|
||||
}
|
||||
return RT_EOK;
|
||||
// 删除旧的信号量(如果存在)
|
||||
if (mount_sem != RT_NULL)
|
||||
{
|
||||
rt_sem_delete(mount_sem);
|
||||
}
|
||||
|
||||
// 创建计数信号量,初始值为 0
|
||||
mount_sem = rt_sem_create("sd_mount", 0, RT_IPC_FLAG_FIFO);
|
||||
if (mount_sem == RT_NULL)
|
||||
{
|
||||
LOG_E("Failed to create semaphore for SD mount!");
|
||||
return -RT_ENOMEM;
|
||||
}
|
||||
|
||||
tid = rt_thread_create("sd_mount",
|
||||
sd_mount,
|
||||
RT_NULL,
|
||||
4096, // 建议增大栈,避免溢出
|
||||
RT_THREAD_PRIORITY_MAX - 2,
|
||||
20);
|
||||
if (tid != RT_NULL)
|
||||
{
|
||||
rt_thread_startup(tid);
|
||||
LOG_I("SD mount thread created and started");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("Failed to create SD mount thread!");
|
||||
rt_sem_delete(mount_sem);
|
||||
mount_sem = RT_NULL;
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
// 使用 INIT_COMPONENTS_INIT 或 INIT_APP_EXPORT 自动启动
|
||||
//INIT_COMPONENTS_INIT(stm32_sdcard_mount); // 在组件初始化阶段运行
|
||||
INIT_APP_EXPORT(stm32_sdcard_mount);
|
||||
Reference in new issue
Block a user