|
|
@ -18,6 +18,7 @@ |
|
|
#define DB_NAME "/sddisk/SC828.db" |
|
|
#define DB_NAME "/sddisk/SC828.db" |
|
|
int db_HelperInit; |
|
|
int db_HelperInit; |
|
|
rt_mq_t db_mq = RT_NULL; //
|
|
|
rt_mq_t db_mq = RT_NULL; //
|
|
|
|
|
|
struct db_command cmd; |
|
|
|
|
|
|
|
|
#define DBG_TAG "dat_sql" |
|
|
#define DBG_TAG "dat_sql" |
|
|
#define DBG_LVL DBG_LOG |
|
|
#define DBG_LVL DBG_LOG |
|
|
@ -96,62 +97,80 @@ static void return_disabled(struct db_command *cmd) { |
|
|
* @brief SELECT 查询回调函数 |
|
|
* @brief SELECT 查询回调函数 |
|
|
*/ |
|
|
*/ |
|
|
static int callback(void *result_str, int argc, char **argv, char **azColName) { |
|
|
static int callback(void *result_str, int argc, char **argv, char **azColName) { |
|
|
char *str = (char *)result_str; |
|
|
//char *buf = (char *)result_str;
|
|
|
int len = rt_strlen(str); |
|
|
int written = rt_strlen(result_str); // 当前已写入长度(假设 buf 是 \0 结尾的)
|
|
|
for (int i = 0; i < argc; i++) { |
|
|
int remaining = MAX_RESULT_LEN - written - 1; // -1 留给最终 \0
|
|
|
rt_snprintf(str + len, MAX_RESULT_LEN - len, "%s=%s|", |
|
|
|
|
|
azColName[i], argv[i] ? argv[i] : "NULL"); |
|
|
if (remaining <= 0) { |
|
|
len = rt_strlen(str); |
|
|
return 0; // 缓冲区已满,不再写入
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < argc && remaining > 0; i++) { |
|
|
|
|
|
const char *val = argv[i] ? argv[i] : "NULL"; |
|
|
|
|
|
// 预估所需长度(保守估计)
|
|
|
|
|
|
int needed = rt_strlen(azColName[i]) + rt_strlen(val) + 2; // + "=...\0" 至少 2 字节(= 和 |)
|
|
|
|
|
|
|
|
|
|
|
|
if (needed > remaining) { |
|
|
|
|
|
break; // 空间不足,停止
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int n = rt_snprintf(result_str + written, remaining + 1, "%s=%s|", azColName[i], val); |
|
|
|
|
|
if (n < 0 || n > remaining) { |
|
|
|
|
|
break; // 写入失败或超限
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
written += n; |
|
|
|
|
|
remaining -= n; |
|
|
|
|
|
} |
|
|
|
|
|
//buf[MAX_RESULT_LEN - 1] = '\0'; // 强制终止,防止意外
|
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/**
|
|
|
/**
|
|
|
* @brief 执行具体 SQL 操作 |
|
|
* @brief 执行具体 SQL 操作 |
|
|
*/ |
|
|
*/ |
|
|
static void handle_db_command(struct db_command *cmd) { |
|
|
static void handle_db_command(struct db_command *cmd_dat) { |
|
|
char *err_msg = 0; |
|
|
char *err_msg = 0; |
|
|
int rc; |
|
|
int rc; |
|
|
|
|
|
|
|
|
switch (cmd->type) |
|
|
switch (cmd_dat->type) |
|
|
{ |
|
|
{ |
|
|
case DB_CMD_INSERT: |
|
|
case DB_CMD_INSERT: |
|
|
case DB_CMD_DELETE: |
|
|
case DB_CMD_DELETE: |
|
|
case DB_CMD_UPDATE: |
|
|
case DB_CMD_UPDATE: |
|
|
case DB_CMD_EXEC: |
|
|
case DB_CMD_EXEC: |
|
|
rc = sqlite3_exec(g_db, cmd->sql, 0, 0, &err_msg); |
|
|
rc = sqlite3_exec(g_db, cmd_dat->sql, 0, 0, &err_msg); |
|
|
if (rc != SQLITE_OK) { |
|
|
if (rc != SQLITE_OK) { |
|
|
cmd->result_code = rc; |
|
|
cmd_dat->result_code = rc; |
|
|
rt_strncpy(cmd->result, err_msg, MAX_RESULT_LEN - 1); |
|
|
rt_strncpy(cmd_dat->result, err_msg, MAX_RESULT_LEN - 1); |
|
|
sqlite3_free(err_msg); |
|
|
sqlite3_free(err_msg); |
|
|
} else { |
|
|
} else { |
|
|
cmd->result_code = 0; |
|
|
cmd_dat->result_code = 0; |
|
|
rt_strncpy(cmd->result, "OK", MAX_RESULT_LEN - 1); |
|
|
rt_strncpy(cmd_dat->result, "OK", MAX_RESULT_LEN - 1); |
|
|
} |
|
|
} |
|
|
break; |
|
|
break; |
|
|
|
|
|
|
|
|
case DB_CMD_SELECT: |
|
|
case DB_CMD_SELECT: |
|
|
cmd->result[0] = '\0'; |
|
|
cmd_dat->result[0] = '\0'; |
|
|
rc = sqlite3_exec(g_db, cmd->sql, callback, cmd->result, &err_msg); |
|
|
rc = sqlite3_exec(g_db, cmd_dat->sql, callback, cmd_dat->result, &err_msg); |
|
|
if (rc != SQLITE_OK) { |
|
|
if (rc != SQLITE_OK) { |
|
|
cmd->result_code = rc; |
|
|
cmd_dat->result_code = rc; |
|
|
rt_strncpy(cmd->result, err_msg, MAX_RESULT_LEN - 1); |
|
|
rt_strncpy(cmd_dat->result, err_msg, MAX_RESULT_LEN - 1); |
|
|
sqlite3_free(err_msg); |
|
|
sqlite3_free(err_msg); |
|
|
} else { |
|
|
} else { |
|
|
cmd->result_code = 0; |
|
|
cmd_dat->result_code = 0; |
|
|
if (cmd->result[0] == '\0') |
|
|
if (cmd_dat->result[0] == '\0')rt_strncpy(cmd_dat->result, "No data", MAX_RESULT_LEN - 1); |
|
|
rt_strncpy(cmd->result, "No data", MAX_RESULT_LEN - 1); |
|
|
|
|
|
} |
|
|
} |
|
|
break; |
|
|
break; |
|
|
|
|
|
|
|
|
case DB_CMD_EXIT: |
|
|
case DB_CMD_EXIT: |
|
|
rt_strncpy(cmd->result, "Exit", MAX_RESULT_LEN - 1); |
|
|
rt_strncpy(cmd_dat->result, "Exit", MAX_RESULT_LEN - 1); |
|
|
cmd->result_code = 0; |
|
|
cmd_dat->result_code = 0; |
|
|
break; |
|
|
break; |
|
|
|
|
|
|
|
|
default: |
|
|
default: |
|
|
cmd->result_code = -1; |
|
|
cmd_dat->result_code = -1; |
|
|
rt_strncpy(cmd->result, "Invalid command", MAX_RESULT_LEN - 1); |
|
|
rt_strncpy(cmd_dat->result, "Invalid command", MAX_RESULT_LEN - 1); |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
@ -257,7 +276,7 @@ void db_sqlite_init_full(void) |
|
|
* @brief 数据库处理线程入口函数 |
|
|
* @brief 数据库处理线程入口函数 |
|
|
*/ |
|
|
*/ |
|
|
static void db_sqlite(void *parameter) { |
|
|
static void db_sqlite(void *parameter) { |
|
|
struct db_command cmd; |
|
|
// struct db_command cmd;
|
|
|
rt_tick_t max_wait_ticks = rt_tick_from_millisecond(DB_MAX_WAITING_MS); |
|
|
rt_tick_t max_wait_ticks = rt_tick_from_millisecond(DB_MAX_WAITING_MS); |
|
|
|
|
|
|
|
|
// 检查并初始化数据库文件
|
|
|
// 检查并初始化数据库文件
|
|
|
@ -357,9 +376,9 @@ static void db_sqlite(void *parameter) { |
|
|
rt_mutex_release(state_mutex); |
|
|
rt_mutex_release(state_mutex); |
|
|
//执行命令
|
|
|
//执行命令
|
|
|
handle_db_command(&cmd); |
|
|
handle_db_command(&cmd); |
|
|
|
|
|
|
|
|
//返回结果
|
|
|
//返回结果
|
|
|
if (cmd.reply_sem != RT_NULL) { |
|
|
if (cmd.reply_sem != RT_NULL) |
|
|
|
|
|
{ |
|
|
rt_sem_release(cmd.reply_sem); |
|
|
rt_sem_release(cmd.reply_sem); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -402,7 +421,7 @@ rt_err_t db_send_command(enum db_cmd_type type, const char* sql, rt_int32_t time |
|
|
return -RT_EINVAL; |
|
|
return -RT_EINVAL; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
struct db_command cmd; |
|
|
//struct db_command cmd;
|
|
|
rt_sem_t sem = rt_sem_create("db_rep", 0, RT_IPC_FLAG_FIFO); |
|
|
rt_sem_t sem = rt_sem_create("db_rep", 0, RT_IPC_FLAG_FIFO); |
|
|
if (sem == RT_NULL) { |
|
|
if (sem == RT_NULL) { |
|
|
return -RT_ENOMEM; |
|
|
return -RT_ENOMEM; |
|
|
@ -437,6 +456,53 @@ rt_err_t db_send_command(enum db_cmd_type type, const char* sql, rt_int32_t time |
|
|
return result; |
|
|
return result; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
rt_err_t db_send_select(enum db_cmd_type type, const char* sql, rt_int32_t timeout_ms, char *result_out) |
|
|
|
|
|
{ |
|
|
|
|
|
if (!sql || !db_mq) { |
|
|
|
|
|
return -RT_EINVAL; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 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; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 初始化命令结构体
|
|
|
|
|
|
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(); |
|
|
|
|
|
|
|
|
|
|
|
// 发送命令到数据库线程队列
|
|
|
|
|
|
if (rt_mq_send(db_mq, &cmd, sizeof(cmd)) != RT_EOK) { |
|
|
|
|
|
rt_sem_delete(sem); |
|
|
|
|
|
return -RT_ERROR; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 计算等待 tick
|
|
|
|
|
|
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); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 等待数据库线程处理完成
|
|
|
|
|
|
rt_err_t result = rt_sem_take(sem, wait_ticks); |
|
|
|
|
|
|
|
|
|
|
|
// 如果调用者提供了 result_out 缓冲区,且是 SELECT 或需要结果,则拷贝
|
|
|
|
|
|
if (result == RT_EOK) { |
|
|
|
|
|
rt_strncpy(result_out, cmd.result, MAX_RESULT_LEN - 1); |
|
|
|
|
|
result_out[MAX_RESULT_LEN - 1] = '\0'; |
|
|
|
|
|
} |
|
|
|
|
|
rt_sem_delete(sem); |
|
|
|
|
|
return result; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
extern struct rt_memheap sram_DTCMRAM; |
|
|
extern struct rt_memheap sram_DTCMRAM; |
|
|
static struct rt_thread dat_sqlite_thread; |
|
|
static struct rt_thread dat_sqlite_thread; |
|
|
static void *dat_sqlite_stack __attribute__((aligned(4)))= RT_NULL ; |
|
|
static void *dat_sqlite_stack __attribute__((aligned(4)))= RT_NULL ; |
|
|
|