日B视频 亚洲,啪啪啪网站一区二区,91色情精品久久,日日噜狠狠色综合久,超碰人妻少妇97在线,999青青视频,亚洲一区二卡,让本一区二区视频,日韩网站推荐

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

實戰(zhàn) | 睿擎平臺SQLite:嵌入式設備上的數(shù)據(jù)持久化方案,從移植到應用一文打通

RT-Thread官方賬號 ? 2026-04-29 19:22 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

嵌入式開發(fā)中,數(shù)據(jù)存儲一直是個剛需:設備參數(shù)配置、傳感器歷史數(shù)據(jù)、運行日志記錄……傳統(tǒng)方案要么用文件系統(tǒng)裸奔,解析麻煩;要么上 SQLite,但移植門檻高、踩坑多。

今天分享一個基于睿擎派 RC3506的完整 SQLite 方案——從源碼移植到 VFS 適配,從 DAO 層封裝到 Shell 調(diào)試,手把手帶你搞定嵌入式數(shù)據(jù)庫。


為什么選 SQLite?

SQLite 是全世界部署最廣泛的 SQL 數(shù)據(jù)庫引擎,沒有之一:

零配置、無服務器:單文件數(shù)據(jù)庫,無需獨立進程,直接嵌入應用

體積極小:核心代碼約 250KB(可裁剪),RAM 占用 250KB 起

全功能 SQL:支持事務、索引、觸發(fā)器、視圖,語法兼容標準 SQL

可靠性極高:原子寫入、故障恢復機制完善,數(shù)據(jù)安全有保障

授權友好:公共域代碼,商用免費,無需開源你的應用

智能手機、汽車電子到工業(yè)網(wǎng)關,SQLite 幾乎無處不在。對于 RT-Thread 嵌入式平臺,它同樣是大型數(shù)據(jù)持久化的常見方案。


架構總覽

整個 SQLite for RT-Thread 方案分五層:

a35cf6ce-43bd-11f1-ab55-92fbcf53809c.png

核心移植工作集中在 VFS 適配層,而 dbhelper 中間層則大幅簡化了應用開發(fā)難度。


移植實戰(zhàn):VFS 適配層詳解

1. 編譯配置(sqlite_config_rtthread.h)

首先需要告訴 SQLite:“我在 RT-Thread 上運行”。關鍵宏定義:

#defineSQLITE_OS_OTHER 1// 不使用默認 OS 層
#defineSQLITE_OS_RTTHREAD 1 // 啟用 RT-Thread VFS
#defineSQLITE_THREADSAFE 1 // 啟用線程安全
#defineSQLITE_OMIT_WAL 1 // 禁用 WAL(減少資源占用)
#defineSQLITE_OMIT_LOAD_EXTENSION 1 // 禁用動態(tài)加載擴展

SQLITE_OMIT_WAL=1 是嵌入式場景的常見選擇:WAL(Write-Ahead Logging)雖然提升并發(fā)性能,但會增加文件數(shù)量和內(nèi)存占用。對于單線程寫入場景,回滾日志模式足夠。


2. VFS 注冊(rtthread_vfs.c)

SQLite 要求所有 VFS 實現(xiàn) sqlite3_vfs 結構體:

staticsqlite3_vfs _rtthread_vfs={
3,// iVersion:VFS 版本號
sizeof(RTTHREAD_SQLITE_FILE_T),// szOsFile:文件句柄大小
RTTHREAD_MAX_PATHNAME,// mxPathname:最大路徑長度(256)
0,// pNext:鏈表指針(內(nèi)部使用)
"rt-thread",// zName:VFS 名稱
0,// pAppData:應用數(shù)據(jù)指針
_rtthread_vfs_open,// xOpen:打開文件
_rtthread_vfs_delete,// xDelete:刪除文件
_rtthread_vfs_access,// xAccess:檢查文件權限
_rtthread_vfs_fullpathname,// xFullPathname:獲取絕對路徑
// ... 其他接口
};

SQLITE_APIintsqlite3_os_init(void)
{
sqlite3_vfs_register(&_rtthread_vfs,1);// 注冊為默認 VFS
returnSQLITE_OK;
}


3. 文件 IO 實現(xiàn)(rtthread_io_methods.c)

核心的讀寫接口,直接調(diào)用 DFS 的 read()/write()/lseek():

staticint_rtthread_io_read(sqlite3_file*file_id,void*pbuf,intcnt,sqlite3_int64 offset)
{
RTTHREAD_SQLITE_FILE_T*file=(RTTHREAD_SQLITE_FILE_T*)file_id;

// 定位到指定偏移
if(lseek(file->fd,offset,SEEK_SET)!=offset){
returnSQLITE_IOERR_READ;
}

// 循環(huán)讀取直到完成(處理 EINTR 中斷)
intr_cnt;
do{
r_cnt=read(file->fd,pbuf,cnt);
if(r_cnt==cnt)break;
if(r_cnt<0&&errno!=EINTR)returnSQLITE_IOERR_READ;
// 處理部分讀取
if(r_cnt>0){
cnt-=r_cnt;
pbuf=(void*)(r_cnt+(char*)pbuf);
}
}while(r_cnt>0);

returnSQLITE_OK;
}

staticint_rtthread_io_write(sqlite3_file*file_id,constvoid*pbuf,intcnt,sqlite3_int64 offset)
{
RTTHREAD_SQLITE_FILE_T*file=(RTTHREAD_SQLITE_FILE_T*)file_id;

if(lseek(file->fd,offset,SEEK_SET)!=offset){
returnSQLITE_IOERR_WRITE;
}

intw_cnt;
do{
w_cnt=write(file->fd,pbuf,cnt);
if(w_cnt==cnt)break;
if(w_cnt<0&&errno!=EINTR)returnSQLITE_IOERR_WRITE;
if(w_cnt>0){
cnt-=w_cnt;
pbuf=(void*)(w_cnt+(char*)pbuf);
}
}while(w_cnt>0);

returnSQLITE_OK;
}

特別注意 EINTR 處理:在實時系統(tǒng)中,系統(tǒng)調(diào)用可能被信號中斷,必須重試。


4. 文件鎖實現(xiàn)(rtthread_io_methods.c)

SQLite 的并發(fā)控制依賴文件鎖。RT-Thread 沒有文件鎖,我們用信號量模擬

typedefstruct{
sqlite3_io_methodsconst*pMethod;
intfd;// 文件描述符
inteFileLock;// 鎖狀態(tài):NO_LOCK/SHARED/EXCLUSIVE
structrt_semaphoresem;// 信號量
}RTTHREAD_SQLITE_FILE_T;

staticint_rtthread_io_lock(sqlite3_file*file_id,inteFileLock)
{
RTTHREAD_SQLITE_FILE_T*file=(RTTHREAD_SQLITE_FILE_T*)file_id;
rt_sem_tpsem=&file->sem;

// 已持有鎖,直接升級級別
if(file->eFileLock>NO_LOCK){
file->eFileLock=eFileLock;
returnSQLITE_OK;
}

// 嘗試獲取信號量
if(rt_sem_trytake(psem)!=RT_EOK){
returnSQLITE_BUSY;// 其他線程持有鎖
}

file->eFileLock=eFileLock;
returnSQLITE_OK;
}

staticint_rtthread_io_unlock(sqlite3_file*file_id,inteFileLock)
{
RTTHREAD_SQLITE_FILE_T*file=(RTTHREAD_SQLITE_FILE_T*)file_id;

if(eFileLock==NO_LOCK){
rt_sem_release(&file->sem);// 釋放信號量
}
file->eFileLock=eFileLock;
returnSQLITE_OK;
}

注意:這是進程內(nèi)鎖,只能防止同一進程內(nèi)的多線程并發(fā)訪問。如果多個進程同時訪問同一數(shù)據(jù)庫文件,仍需依賴文件系統(tǒng)的鎖機制或外部協(xié)調(diào)。


5. 隨機數(shù)與時間戳

SQLite 內(nèi)部需要隨機數(shù)(生成臨時文件名)和當前時間戳:

staticint_rtthread_vfs_randomness(sqlite3_vfs*pvfs,intnByte,char*zOut)
{
chartick8=(char)rt_tick_get();
chartick16=(char)(rt_tick_get()>>8);

for(inti=0;i<nByte;i++){
zOut[i]=(char)(i^tick8^tick16);
tick8=zOut[i];
tick16=~(tick8^tick16);
}
returnnByte;
}

staticint_rtthread_vfs_current_time_int64(sqlite3_vfs*pvfs,sqlite3_int64*pnow)
{
time_tt;
time(&t);
*pnow=((sqlite3_int64)t)*1000+24405875*(sqlite3_int64)8640000;
returnSQLITE_OK;
}


中間層封裝:dbhelper 設計

直接調(diào)用 SQLite 原生 API 門檻較高:需要手動管理 sqlite3_stmt、處理錯誤碼、編寫回滾邏輯。dbhelper 封裝了常用操作,讓應用層代碼更簡潔。

初始化

intdb_helper_init(void)
{
sqlite3_initialize();// 初始化 SQLite 內(nèi)部狀態(tài)
db_mutex_lock=rt_mutex_create("dbmtx",RT_IPC_FLAG_FIFO);
returnRT_EOK;
}
INIT_APP_EXPORT(db_helper_init);// 自動初始化

數(shù)據(jù)庫創(chuàng)建

intdb_create_database(constchar*sqlstr)
{
returndb_nonquery_operator(sqlstr,0,0);
}

// 使用示例
constchar*sql="CREATE TABLE student("
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
"name VARCHAR(32) NOT NULL,"
"score INT NOT NULL);";
db_create_database(sql);

帶數(shù)據(jù)綁定的批量插入

intdb_nonquery_operator(constchar*sqlstr,
int(*bind)(sqlite3_stmt*,int,void*),
void*param);

關鍵優(yōu)化:一條 SQL 語句只編譯一次,然后循環(huán)綁定數(shù)據(jù)執(zhí)行,大幅提升批量操作性能。

// 插入學生數(shù)據(jù)
staticintstudent_insert_bind(sqlite3_stmt*stmt,intindex,void*arg)
{
rt_list_t*h=arg;
student_t*s;
rt_list_for_each_entry(s,h,list){
sqlite3_reset(stmt);
sqlite3_bind_text(stmt,1,s->name,strlen(s->name),NULL);
sqlite3_bind_int(stmt,2,s->score);
sqlite3_step(stmt);
}
returnSQLITE_OK;
}

db_nonquery_operator("INSERT INTO student(name,score) VALUES(?,?);",
student_insert_bind,&student_list);

內(nèi)部已開啟事務,失敗自動回滾。

注意:db_nonquery_by_varpara() 是單條 SQL 執(zhí)行,不支持事務。如需事務,請使用 db_nonquery_operator() 或 db_nonquery_transaction()。

帶變參的查詢

intdb_query_by_varpara(constchar*sql,
int(*create)(sqlite3_stmt*,void*),
void*arg,
constchar*fmt,...);

// 查詢指定 ID 的學生
staticintstudent_create(sqlite3_stmt*stmt,void*arg)
{
student_t*s=arg;
if(sqlite3_step(stmt)!=SQLITE_ROW)return0;
s->id=db_stmt_get_int(stmt,0);
db_stmt_get_text(stmt,1,s->name);
s->score=db_stmt_get_int(stmt,2);
returnSQLITE_OK;
}

student_ts;
db_query_by_varpara("SELECT * FROM student WHERE id=?;",
student_create,&s,"%d",student_id);

實戰(zhàn)示例:學生成績管理系統(tǒng)

示例工程 12_data_parsers_sqlite 實現(xiàn)了一個完整的學生成績管理 DAO 層。

表結構設計

CREATETABLEstudent(
idINTEGERPRIMARYKEYAUTOINCREMENT,
nameVARCHAR(32)NOTNULL,
scoreINTEGERNOTNULL
);

DAO 層核心接口

// 增:批量插入學生
intstudent_add(rt_list_t*h);

// 刪:按 ID 刪除或刪除全部
intstudent_del(intid);
intstudent_del_all(void);

// 改:更新學生信息
intstudent_update(student_t*s);

// 查:按 ID 查詢單個,或查詢?nèi)?/span>
intstudent_get_by_id(student_t*s,intid);
intstudent_get_all(rt_list_t*q);

// 條件查詢:按分數(shù)區(qū)間查詢,支持升序/降序
intstudent_get_by_score(rt_list_t*h,intlow,inthigh,enumorder_typeorder);

Shell 命令調(diào)試

示例提供了完整的 Shell 命令,方便調(diào)試:

msh />create_student_tbl # 創(chuàng)建數(shù)據(jù)庫和表
Database path: /data/stu_info.db

msh />stuadd100# 批量插入 100 條記錄
Insert100record(s): 125ms, speed: 1ms/record

msh />stu # 查詢?nèi)?/span>
id:1 name:Student1234 score:87
id:2 name:Student5678 score:92
...
record(s):100

msh />stu score60100-d # 查詢 60-100 分,降序排列
id:88 name:Student9999 score:99
id:42 name:Student1234 score:95
...

msh />stu update1Alice100# 更新記錄
update record success!

msh />stu del1# 刪除指定記錄
Del record success with id:1

msh />stu del # 刪除全部
Del all record success!

資源占用

資源

最小配置

典型配置

RAM

250KB

500KB+

ROM

310KB

500KB+

棧空間

4KB

8KB

睿擎派 RC3506(RK3506,512MB DDR)完全滿足需求。如果資源緊張,可通過 SQLITE_OMIT_* 宏裁剪不需要的功能。


總結

SQLite 為嵌入式設備提供了企業(yè)級的數(shù)據(jù)管理能力,而 RT-Thread 的 VFS 適配層讓移植工作變得簡單。通過 dbhelper 中間層封裝,應用開發(fā)者無需深入了解 SQLite API,就能快速實現(xiàn)數(shù)據(jù)持久化功能。

關鍵要點回顧:

VFS 適配層是移植核心,實現(xiàn)文件 IO、鎖、隨機數(shù)、時間戳

dbhelper 封裝了事務、數(shù)據(jù)綁定、錯誤處理,大幅簡化應用代碼

Prepared Statement + 事務是批量操作的性能關鍵

單寫者模型:多線程讀,單線程寫,避免鎖競爭

完整示例代碼已集成到睿擎 SDK V2604,歡迎體驗!

配套資料包

想在自己的項目里復現(xiàn) SQLite 移植?我們整理了完整資料包,助你快速上手:

SQLite 移植源碼包(含 VFS 適配層、dbhelper 封裝)

交叉編譯腳本與集成示例(RuiChing Studio 可直接導入)

學生成績管理 DAO 層完整代碼

本篇文章涉及的全部 SQL 腳本與 Shell 命令

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    DeepSeekQwen,AI大模型的移植與交互實戰(zhàn)指南-飛凌嵌入式

    在不久前發(fā)布的《技術實戰(zhàn)|OK3588-C開發(fā)板上部署DeepSeek-R1大模型的完整指南》中,小編為大家介紹了DeepSeek-R1在飛凌嵌入式OK3588-C開發(fā)板
    的頭像 發(fā)表于 03-28 08:06 ?3063次閱讀
    <b class='flag-5'>從</b>DeepSeek<b class='flag-5'>到</b>Qwen,AI大模型的<b class='flag-5'>移植</b>與交互<b class='flag-5'>實戰(zhàn)</b>指南-飛凌<b class='flag-5'>嵌入式</b>

    派文件系統(tǒng)指南:開發(fā)到發(fā)布全流程實踐 | 技術解析

    嵌入式系統(tǒng)開發(fā)中,文件系統(tǒng)扮演著至關重要的角色,它負責數(shù)據(jù)持久存儲、配置文件管理和資源訪問等核心功能。
    的頭像 發(fā)表于 11-05 18:13 ?8336次閱讀
    <b class='flag-5'>睿</b><b class='flag-5'>擎</b>派文件系統(tǒng)指南:<b class='flag-5'>從</b>開發(fā)到發(fā)布全流程實踐 | 技術解析

    嵌入式系統(tǒng)到底該選哪款數(shù)據(jù)庫,SQLite真的是最優(yōu)解嗎?

    數(shù)據(jù)庫選型的最優(yōu)解嗎?在邊緣計算、物聯(lián)網(wǎng)網(wǎng)關、嵌入式系統(tǒng)中,數(shù)據(jù)往往是各種傳感器或設備采集的時序數(shù)據(jù),這些
    發(fā)表于 02-11 11:02

    嵌入式數(shù)據(jù)sqlite移植及使用的資料分享

    嵌入式數(shù)據(jù)sqlite移植及使用、實驗目的二.實驗內(nèi)容三.預備知識四.實驗設備及工具(包括軟
    發(fā)表于 10-28 09:48

    sqlite3是如何移植嵌入式Linux

    sqlite可以說是目前使用最廣泛的文件型數(shù)據(jù)庫,嵌入式設備的首選。據(jù)說iphone手機和微信的數(shù)據(jù)
    發(fā)表于 11-04 08:58

    如何將sqlite3移植嵌入式Linux開發(fā)板M6708

    原文鏈接:添加鏈接描述最近,因為項目的需要,我們購買了廣州致遠電子有限公司的M6708-T工控板(預裝Linux系統(tǒng)),準備將sqlite3移植嵌入式開發(fā)板
    發(fā)表于 12-27 07:26

    嵌入式數(shù)據(jù)Sqlite移植教程

    嵌入式數(shù)據(jù)Sqlite移植教程 sqlite-3.3.6編譯安裝與交叉編譯全過程詳細記錄
    發(fā)表于 03-11 09:57 ?4087次閱讀

    SQLite嵌入式Wince中的應用

    應該盡量小,SQLite[1]在Linux中的應用很廣泛,本設計介紹了SQLite作為款小巧的嵌入式數(shù)據(jù)庫在Wince[2]中的應用實例。
    發(fā)表于 11-30 08:55 ?840次閱讀
     <b class='flag-5'>SQLite</b>在<b class='flag-5'>嵌入式</b>Wince中的應用

    如何吧SQLite移植嵌入式Linux系統(tǒng)的詳細資料說明

    本文檔的主要內(nèi)容詳細介紹的是如何吧SQLite移植嵌入式Linux系統(tǒng)的詳細資料說明。
    發(fā)表于 01-18 08:00 ?8次下載
    如何吧<b class='flag-5'>SQLite</b><b class='flag-5'>移植</b><b class='flag-5'>到</b><b class='flag-5'>嵌入式</b>Linux系統(tǒng)的詳細資料說明

    嵌入式實驗】《嵌入式數(shù)據(jù)sqlite 移植及使用》

    嵌入式數(shù)據(jù)sqlite 移植及使用、實驗目的二.實驗內(nèi)容三.預備知識四.實驗設備及工具(包
    發(fā)表于 10-21 10:51 ?6次下載
    【<b class='flag-5'>嵌入式</b>實驗】《<b class='flag-5'>嵌入式</b><b class='flag-5'>數(shù)據(jù)</b>庫 <b class='flag-5'>sqlite</b> <b class='flag-5'>移植</b>及使用》

    sqlite3移植嵌入式Linux

    sqlite可以說是目前使用最廣泛的文件型數(shù)據(jù)庫,嵌入式設備的首選。據(jù)說iphone手機和微信的數(shù)據(jù)
    發(fā)表于 11-01 17:21 ?13次下載
    <b class='flag-5'>sqlite</b>3<b class='flag-5'>移植</b><b class='flag-5'>到</b><b class='flag-5'>嵌入式</b>Linux

    明晚8點|文件系統(tǒng)實戰(zhàn)開發(fā)到發(fā)布全流程解析

    文件操作到鏡像發(fā)布,次直播掌握完整開發(fā)流程!在嵌入式系統(tǒng)開發(fā)中,文件系統(tǒng)是數(shù)據(jù)存儲、配置管理和資源訪問的核心基礎。然而在實際開發(fā)中,文件操作效率低下、鏡像打包流程復雜、系統(tǒng)發(fā)布困難
    的頭像 發(fā)表于 11-11 11:53 ?814次閱讀
    明晚8點|<b class='flag-5'>睿</b><b class='flag-5'>擎</b>文件系統(tǒng)<b class='flag-5'>實戰(zhàn)</b>:<b class='flag-5'>從</b>開發(fā)到發(fā)布全流程解析

    【直播預告】下周三晚8點|物聯(lián)網(wǎng)實戰(zhàn)傳感器采集MQTT云全流程解析

    傳感器采集云端通信,次直播打通物聯(lián)網(wǎng)全鏈路開發(fā)!在物聯(lián)網(wǎng)應用開發(fā)中,傳感器數(shù)據(jù)采集不穩(wěn)定、外設配置復雜、云端通信不可靠等問題常常困擾著
    的頭像 發(fā)表于 11-21 17:07 ?2220次閱讀
    【直播預告】下周三晚8點|<b class='flag-5'>睿</b><b class='flag-5'>擎</b>物聯(lián)網(wǎng)<b class='flag-5'>實戰(zhàn)</b>:<b class='flag-5'>從</b>傳感器采集<b class='flag-5'>到</b>MQTT<b class='flag-5'>上</b>云全流程解析

    明晚:物聯(lián)網(wǎng)實戰(zhàn)傳感器采集MQTT云全流程解析|問學直播

    傳感器采集云端通信,次直播打通物聯(lián)網(wǎng)全鏈路開發(fā)!在物聯(lián)網(wǎng)應用開發(fā)中,傳感器數(shù)據(jù)采集不穩(wěn)定、外設配置復雜、云端通信不可靠等問題常常困擾著
    的頭像 發(fā)表于 11-25 18:31 ?573次閱讀
    明晚:<b class='flag-5'>睿</b><b class='flag-5'>擎</b>物聯(lián)網(wǎng)<b class='flag-5'>實戰(zhàn)</b>:<b class='flag-5'>從</b>傳感器采集<b class='flag-5'>到</b>MQTT<b class='flag-5'>上</b>云全流程解析|問學直播

    直播預告 | 開源軟件包移植適配專題(第1期):SQLite 入門精通

    嵌入式數(shù)據(jù)庫在資源受限設備跑不動?交叉編譯SQLite總是缺依賴、配置難?想在AMP雙系統(tǒng)下統(tǒng)一數(shù)據(jù)
    的頭像 發(fā)表于 04-24 18:05 ?432次閱讀
    直播預告 | 開源軟件包<b class='flag-5'>移植</b>適配專題(第1期):<b class='flag-5'>SQLite</b> <b class='flag-5'>從</b>入門<b class='flag-5'>到</b>精通
    麻阳| 平罗县| 抚松县| 襄汾县| 邹平县| 从江县| 虹口区| 普陀区| 社会| 台湾省| 来宾市| 邓州市| 手机| 望江县| 健康| 通许县| 库车县| 江油市| 大厂| 锡林浩特市| 岳阳市| 报价| 天镇县| 深圳市| 高平市| 大港区| 浦北县| 黄石市| 平邑县| 赤水市| 娄烦县| 腾冲县| 西华县| 海宁市| 肇东市| 延寿县| 文水县| 邵东县| 芷江| 普陀区| 梅州市|