鴻蒙Hi3861 NV操作——如何保存數據到開發板,斷電不丟失
想了解更多內容,請訪問:
51CTO和華為官方合作共建的鴻蒙技術社區
https://harmonyos.51cto.com/#zz
實際產品開發過程中,我們肯定需要保存一些數據,并且掉電不丟失。例如很多人在使用我之前寫的一篇WiFi配網功能后,都會遇到一個問題:我配置了WiFi賬戶密碼,但是下次我又得重新配網,能不能把WiFi賬戶密碼保存起來?
好,接下來我們來實現這個功能:保存數據到開發板,斷電不丟失。
有兩種方式:
1、使用KV系統——最簡單,推薦使用
關于如何保存數據的,可以直接使用 kv系統更加簡單方便,不必參考本文的 nv操作,本文nv操作僅供大家參考。
kv系統可以保存數據到flash,只需要簡單的兩個函數即可:
//刪除kv
void DeleteKVCache(const char* key);
//增加kv
void AddKVCache(const char* key, const char* value, boolean isNew);
//獲取kv值
int GetValueByCache(const char* key, char* value, unsigned int maxLen);
//清除kv
int ClearKVCacheInner(void);
例如:
//把ssid寫入到kv中
AddKVCache("ssid", ssid, TRUE);
//讀取出來kv
GetValueByCache("ssid",ssid,sizeof(ssid));
可以看到更加簡單高效~~推薦大家使用
2、NV系統——僅hi3861支持
首先我們要使用到 hi3861 的nv操作,它支持我們自定義一些數據保存到工廠參數分區,其實就是寫入到hi3861的flash中。
不過這個功能使用挺復雜的,我們以保存wifi賬戶密碼為例。
1、修改 mss_nvi_db.xml 文件
打開vendor\hisi\hi3861\hi3861\tools\nvtool\xml_file\mss_nvi_db.xml 文件,在 Factory 中增加我們的參數:ID為0x0B 。

截圖的內容是這個:
- <NV ID="0x0B" NAME="INIT_CONFIG_SSID_MY" PARAM_NAME="wal_cfg_ssid_my" PARAM_VALUE="{[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}" CATEGORY="FTM" DEV="CCO-STA-NDM" DESCRIPTION="" />
2、修改 nv_factory_struct_def.txt 文件 增加 結構體
修改 vendor\hisi\hi3861\hi3861\tools\nvtool\h_file\nv\nv_factory_struct_def.txt,增加結構體:
- typedef struct {
- hi_u8 ssid[50];
- hi_u8 passwd[50];
- } wal_cfg_ssid_my;
3、編寫代碼,讀取寫入數據
通常來說,需要先執行一次 hi_nv_init(0xA000, 0x2000, 0x1000); 進行初始化,但是由于系統啟動的時候已經初始化過了,所以我們不需要重復初始化。
- //寫入到工廠區
- /* NV值寫入 */
- wal_cfg_ssid_my nv;
- memset(&nv, 0, sizeof(wal_cfg_ssid_my));
- memcpy_s(&nv.ssid[0], sizeof(wal_cfg_ssid_my), ssid, ssid_len);
- memcpy_s(&nv.passwd[0], sizeof(wal_cfg_ssid_my), passwd, passwd_len);
- ret = hi_factory_nv_write(NV_ID, &nv, sizeof(wal_cfg_ssid_my), 0);
- if (ret != HISI_OK) {
- printf("%x\n", ret);
- }
- /* 再次讀取寫入的NV值 */
- ret = hi_factory_nv_read(NV_ID, &nv, sizeof(wal_cfg_ssid_my), 0);
- if (ret != HISI_OK) {
- printf("%x\n", ret);
- }
- printf("nv read : %d, ssid :[%s] psswd [%s]\n",ret, nv.ssid, nv.passwd);
附件我提供了一個wifi配網的升級版功能的源碼,支持保存wifi賬號密碼。
完成以上操作后,我們就可以發現wifi賬戶密碼可以寫入到nv中了,可以永久保存數據了。查看開機打印:

可以看到開機后讀取到ssid 和密碼正確,并且成功連接到wifi熱點了。
我們再來看這個nv的一些內容吧:
mss_nvi_db.xml 文件記錄了所有系統參數的默認值,而且這個文件其實還分組的:

可以看到分為 Factory 和 Modem。
NV模塊用于管理系統關鍵配置信息。 NV存儲于Flash上,分為以下2個區:
● 工廠區 Factory:僅在工廠時使用。
● 非工廠區 Modem :分為以下2個區:
– Keep區: NV項在升級后保留原值
– Modem區: NV項在升級后被新版本值替換。

關于
- <GROUP NAME="Factory" ID="0x3" FEATURE="1<<0,1<<5" USEDMODE="0" PARAM_DEF_FILE="../nv/nv_factory_struct_def.txt">
每一項的說明如下:

關于
- <NV ID="0x0B" NAME="INIT_CONFIG_SSID_MY" PARAM_NAME="wal_cfg_ssid_my" PARAM_VALUE="{[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}" CATEGORY="FTM" DEV="CCO-STA-NDM" DESCRIPTION="" />
的每一項說明如下:

另外需要注意的是工廠區的讀寫操作跟非工廠區的讀寫操作的API不同。

想了解更多內容,請訪問:
51CTO和華為官方合作共建的鴻蒙技術社區
https://harmonyos.51cto.com/#zz