串口1,485功能。
数据接收解析及数据库处理
This commit is contained in:
1 parent
e36baf375d
commit
0735772f8a
19 files changed
+2066
-228
No files matched your search
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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 */
|
||||
};
|
||||
|
||||
/* ========================
|
||||
|
||||
Reference in new issue
Block a user