不知道自己是哪根筋搭錯了還是怎麼回事,一時心血來潮,突發奇想,決定把sqlite移植到stm32f429上。在此記錄一下過程,也確認一下此事可行。
先說一下結果:移植後的sqlite可執行,可操作,但是比較耗資源(相對微控制器來說),記憶體小的,就別想了,根本玩不起來的。
這是未載入時的記憶體使用情況:
這是開啟資料庫時記憶體的情況:
這是使用查詢後的記憶體使用情況:
從記憶體使用的情況上來看,小微控制器就算了,即使是stm32f429,高達192k的記憶體,也經不起這樣折騰,還是得老實點加外存。
ok,結果也看了,現在來說說移植要點。
背景:stm32f429,32m外存sdram。rtt。fatfs。sd卡。
一切在sqlite的說明文件時已經交待清楚了,這裡只是重複一下原作者的宣告而已。
1、用替代實現替換內建的互斥鎖子系統。
2、完全禁用在單執行緒應用程式中使用的所有靜音。
3、重新配置記憶體分配子系統,以使用標準庫中的malloc()實現以外的其他記憶體分配器。
4、重新對齊記憶體分配子系統,以便它根本不會呼叫malloc(),而是使用在啟動時分配給sqlite的固定大小的記憶體緩衝區來滿足所有記憶體請求。
5、用替代設計替換檔案系統的介面。換句話說,覆蓋sqlite進行的所有系統呼叫,以便使用一組完全不同的系統呼叫與磁碟進行對話。
6、覆蓋其他作業系統介面,例如獲取zulu或本地時間的呼叫。
其實以上六條只是三個子系統的介面需要處理。分別是:
1、配置或替換mutex子系統
2、配置或更換記憶體分配子系統
3、新增新的虛擬檔案系統
最後補全這兩個函式
sqlite3_os_init()
sqlite3_os_end()
做好上述工作,寫個簡單的測試程式。ok,接下來就可以放心測試調整了。
值得說的是:
仔細觀察記憶體使用,這耗費了我太多的時間。棧空間從2k起,一直調整到16k,才算勉強成功。
另外:得了解posix,若是你沒有這個基礎,需要花點時間了解下什麼標準操作介面。
得了解vfs,若是你不知道這是什麼東西,需要了解下虛擬檔案系統的組成及原理。
得了解下微控制器是怎麼操作外存的,尤其是stm32fx系列,我用的是keil mdk,外掛程式32msdram。
至於在除錯過程中會遇到莫名其妙的出錯時,請不要懷疑sqlite,把shell的棧空間放大點,至少到16k。2k是肯定不要想了,4k只夠開啟資料庫,8k免強可以查詢一下,16k測試下還目前還算穩定。
sqlite作者的原話:
為了將sqlite移植到新的作業系統(預設情況下不支援該作業系統),應用程式必須提供…
1、有效的互斥子系統(但僅在多執行緒的情況下),
2、乙個工作的記憶體分配子系統(假設它在其標準庫中缺少malloc()),
3、並且有效的vfs實施。
ok,從一開始,我拼命折騰sqlite原始碼,各種巨集開關修改了個遍,最後才發現其實只要額外定義幾個作者描述的巨集之外,根本不需要動任何東西。事實上我最終也沒有動任何原始碼,另外加了乙個標頭檔案用於宣告巨集開關。
若是想移植到freertos,注意上面的三點,仿照rtt重寫部分介面,一定會成功的。小夥伴們不要在sqlite原始碼裡折騰了。
這是測試檔案,移植**不附了。請參考rtt就行。
#include
"stdio.h"
#include
"sqlite3.h"
#include
"rtthread.h"
#include
"string.h"
sqlite3 *db;
void
db_open()
rt_kprintf
("open database success!\r\n");
}msh_cmd_export
(db_open,sqlite3 runing)
;void
db_close()
msh_cmd_export
(db_close,sqlite3 closed)
;static
intcallback_create
(void
*notused,
int argc,
char
**ar**,
char
**azcolname)
rt_kprintf
("\n");
return0;
}void
createtable
(void
)else
sqlite3_close
(db);}
msh_cmd_export
(createtable,create table)
;//控制台呼叫形式:
// insert 5 murphy 32 california 2000.00
void
insert
(int argc,
char
**ar**)
;/* create sql statement */
// sql = "insert into company (id,name,age,address,salary) " \
// "values (6, 'murphy2', 32, 'california', 20000.00 ); ";
sql =
"insert into company (id,name,age,address,salary) values ("
;//6, 'murphy2', 32, 'california', 20000.00 ); ";
strcpy
(sqlcmd,sql)
;strcat
(sqlcmd,ar**[1]
);//id
strcat
(sqlcmd,
", '");
strcat
(sqlcmd,ar**[2]
);//name
strcat
(sqlcmd,
"', ");
strcat
(sqlcmd,ar**[3]
);//age
strcat
(sqlcmd,
", '");
strcat
(sqlcmd,ar**[4]
);//address
strcat
(sqlcmd,
"', ");
strcat
(sqlcmd,ar**[5]
);//salary
strcat
(sqlcmd,
"); ");
/* execute sql statement */
rc =
sqlite3_exec
(db, sqlcmd, callback_create,0,
&zerrmsg);if
( rc != sqlite_ok )
else
}msh_cmd_export
(insert,insert record to table)
;static
intcallback_query
(void
*data,
int argc,
char
**ar**,
char
**azcolname)
rt_kprintf
("\n");
return0;
}void
query()
else
}msh_cmd_export
(query,query infomation from table)
;static
intcallback_delete
(void
*data,
int argc,
char
**ar**,
char
**azcolname)
rt_kprintf
("\n");
return0;
}//呼叫形式:deletebyid 10 刪除id = 10 的一條記錄
void
deletebyid
(int argc,
char
**ar**)
;strcpy
(sqlcmd,sql)
;strcat
(sqlcmd,ar**[1]
); rc =
sqlite3_exec
(db,sqlcmd,callback_query,
(void
*)data,
&zerrmsg);}
msh_cmd_export
(deletebyid,delete infomation from table)
;
STM32F429除錯記錄(一)
stm32f429的晶元有兩路can介面 四路串列埠 內部乙太網以及內部dsp處理器等硬體,硬體的豐富程度可見一斑,而且主頻達到180mhz,雖然比a8 a9架構的arm晶元還是差一大截,但是在工業控制上的應用還是比較多的。在程式編寫方面stm32f4系列不管在mdk還是庫函式都有挺大改動,剛著手除...
STM32F429 如何使用SDRAM
關於stm32f429 控制sdram fmc 擴充套件外部sdram 1 原理介紹 為什麼是fmc 不是 fsmc 區別在那裡!stm32f429使用fmc外設來管理擴充套件的儲存器,fmc是flexible memory controller的縮寫,譯為可變儲存控制器。它可以用於驅動包括sram...
STM32F429 如何使用NAND Flash
1 原理介紹 flash即是儲存晶元的一種,其結合了rom和ram的特點,既具備電可擦除程式設計的效能,又可以快速讀取資料,資料不會因斷電丟失。目前市面上flash主要有nor flash和nand flash。nor flash具有隨機訪問和隨位元組執行寫操作的能力,即可以訪問到儲存器內部的任意乙...