串口1,485功能。

数据接收解析及数据库处理
This commit is contained in:
sc committed 2025-11-29 02:03:29 +08:00
1 parent e36baf375d
commit 0735772f8a
19 files changed
+2066 -228

No files matched your search

+57 -80
View File
@@ -282,10 +282,10 @@ static void db_sqlite(void *parameter) {
// 默认启用数据库
db_enabled = RT_TRUE;
while (1) {
rt_thread_mdelay(500);
while (1)
{
// 接收命令
if (rt_mq_recv(db_mq, &cmd, sizeof(struct db_command), RT_WAITING_FOREVER) != RT_EOK)
if (rt_mq_recv(db_mq, &cmd, sizeof(struct db_command), RT_WAITING_FOREVER) <= RT_EOK)
continue;
//检查排队超时
@@ -310,30 +310,32 @@ static void db_sqlite(void *parameter) {
if (cmd.type == DB_CMD_EXIT) break;
continue;
}
//打开数据库(如果未打开)
rt_mutex_take(state_mutex, RT_WAITING_FOREVER);
if (!g_db && current_enabled)
{
if (!g_db && current_enabled) {
int rc = sqlite3_open(DB_NAME, &g_db);
if (rc != SQLITE_OK) {
rt_kprintf("Failed to open DB at %s: %s\n", DB_NAME, sqlite3_errmsg(g_db));
sqlite3_close(g_db);
g_db = RT_NULL;
rt_mutex_release(state_mutex);
return_disabled(&cmd);
continue;
} else {
rt_kprintf("Opened database: %s\n", DB_NAME);
}
int rc = sqlite3_open(DB_NAME, &g_db);
if (rc != SQLITE_OK)
{
rt_kprintf("Failed to open DB at %s: %s\n", DB_NAME, sqlite3_errmsg(g_db));
sqlite3_close(g_db);
g_db = RT_NULL;
rt_mutex_release(state_mutex);
return_disabled(&cmd);
continue;
} else {
rt_kprintf("Opened database: %s\n", DB_NAME);
}
}
rt_mutex_release(state_mutex);
//执行命令
handle_db_command(&cmd);
//返回结果
if (cmd.reply_sem) {
if (cmd.reply_sem != RT_NULL) {
rt_sem_release(cmd.reply_sem);
}
@@ -372,80 +374,55 @@ static void db_sqlite(void *parameter) {
*/
rt_err_t db_send_command(enum db_cmd_type type, const char* sql, rt_int32_t timeout_ms)
{
struct db_command cmd;
rt_sem_t sem = RT_NULL;
rt_err_t result = RT_EOK;
if (!sql || !db_mq) {
return -RT_EINVAL;
}
// 1. 创建临时信号量用于同步
sem = rt_sem_create("db_rep", 0, RT_IPC_FLAG_FIFO);
if (sem == RT_NULL)
{
rt_kprintf("Failed to create reply semaphore!\n");
return -RT_ENOMEM;
}
struct db_command cmd;
rt_sem_t sem = rt_sem_create("db_rep", 0, RT_IPC_FLAG_FIFO);
if (sem == RT_NULL) {
return -RT_ENOMEM;
}
// 2. 构造命令
rt_memset(&cmd, 0, sizeof(cmd));
cmd.type = type;
rt_strncpy(cmd.sql, sql, MAX_SQL_LEN - 1);
cmd.reply_sem = sem;
cmd.send_tick = rt_tick_get();
// 初始化命令结构体
rt_memset(&cmd, 0, sizeof(cmd));
cmd.type = type;
rt_strncpy(cmd.sql, sql, MAX_SQL_LEN - 1);
cmd.reply_sem = sem;
cmd.send_tick = rt_tick_get();
// 3. 发送命令到消息队列
if (rt_mq_send(db_mq, &cmd, sizeof(cmd)) != RT_EOK)
{
rt_kprintf("Failed to send command to db_mq!\n");
rt_sem_delete(sem);
return -RT_ERROR;
}
// 发送命令到数据库线程队列
if (rt_mq_send(db_mq, &cmd, sizeof(cmd)) != RT_EOK) {
rt_sem_delete(sem);
return -RT_ERROR;
}
// 4. 等待数据库线程处理完成(超时保护)
if (timeout_ms > 0)
{
rt_int32_t tick = rt_tick_from_millisecond(timeout_ms);
result = rt_sem_take(sem, tick);
}
else
{
result = rt_sem_take(sem, RT_WAITING_FOREVER); // 永久等待(慎用)
}
// 计算等待 tick(兼容 RT_WAITING_FOREVER)
rt_int32_t wait_ticks;
if (timeout_ms == RT_WAITING_FOREVER) {
wait_ticks = RT_WAITING_FOREVER;
} else if (timeout_ms <= 0) {
wait_ticks = 0; // 立即超时
} else {
wait_ticks = rt_tick_from_millisecond(timeout_ms);
}
// 5. 检查结果
if (result == RT_EOK)
{
rt_kprintf("SQL executed: code=%d\n", cmd.result_code);
if (type == DB_CMD_SELECT || strlen(cmd.result) > 0)
{
rt_kprintf("Result: %s\n", cmd.result);
}
}
else if (result == -RT_ETIMEOUT)
{
rt_kprintf("Database response timeout!\n");
}
else
{
rt_kprintf("Wait failed: %d\n", result);
}
// 6. 删除信号量
rt_sem_delete(sem);
return result;
// 等待数据库线程处理完成
rt_err_t result = rt_sem_take(sem, wait_ticks);
//rt_sem_delete(sem);
return result;
}
/* 线程 */
void thread_DB_SQLite(void)
{
rt_thread_t tid;
tid = rt_thread_create("db_sql", db_sqlite, RT_NULL, 1024 *32, 20, 10);
tid = rt_thread_create("db_sql", db_sqlite, RT_NULL, 1024 *48, 20, 10);
if (tid != RT_NULL)
{
rt_thread_startup(tid);
}
else
{
LOG_D("Failed to create SQLite thread!\n");
}
if (tid != RT_NULL)
{
rt_thread_startup(tid);
}else{
LOG_D("Failed to create SQLite thread!\n");
}
}
+3 -1
View File
@@ -6,9 +6,10 @@
* Change Logs:
* Date Author Notes
* 2025-10-20 Administrator the first version
* 2025-11-29 Qwen Add auto_delete_sem to fix semaphore UAF
*/
#ifndef APPLICATIONS_DB_DB_SQLITE_H_
#define APPLICATIONS_DB_SQLITE_SYS_H_
#define APPLICATIONS_DB_DB_SQLITE_H_ // ← 注意:修正宏名,与文件路径一致(原为 _SYS_H_)
#include <rtthread.h>
@@ -69,6 +70,7 @@ struct db_command
char result[MAX_RESULT_LEN]; /**< 结果或错误信息 */
rt_sem_t reply_sem; /**< 回应信号量(由调用方创建,用于同步) */
rt_tick_t send_tick; /**< 发送时刻的系统 tick,用于超时检测 */
rt_bool_t auto_delete_sem; /**< 是否由数据库线程自动删除 reply_sem */
};
/* ========================