CC2640R2F学习笔记(16)——SNV Flash使用
一、背景
SNV(Simple Non-Volatile,簡單的非易揮發(fā)),是從內(nèi)部 flash 末尾劃分大約 1~4K大小的一塊專用于存儲數(shù)據(jù)的存儲空間。一般用于存儲協(xié)議棧必要的存儲數(shù)據(jù)、用戶的應(yīng)用數(shù)據(jù)。類似于 STM32 的片內(nèi) EEPROM。
NV(Non-Volatile,非易揮發(fā)) 是 16 位 ID,而 SNV 是簡化版的 NV 只有 8 位 ID。
1.1 SNV大小
兩頁,共 4K(協(xié)議棧已使用一部分)。
1.2 可用SNV的ID號
在Bcomdef.h中
// Device NV Items - Range 0 - 0x1F #define BLE_NVID_IRK 0x02 //!< The Device's IRK #define BLE_NVID_CSRK 0x03 //!< The Device's CSRK #define BLE_NVID_SIGNCOUNTER 0x04 //!< The Device's Sign Counter #define BLE_LRU_BOND_LIST 0x05 //!< The Device's order of bond indexes in least recently used order// Bonding NV Items - Range 0x20 - 0x5F - This allows for 10 bondings #define BLE_NVID_GAP_BOND_START 0x20 //!< Start of the GAP Bond Manager's NV IDs #define BLE_NVID_GAP_BOND_END 0x5f //!< End of the GAP Bond Manager's NV IDs Range// GATT Configuration NV Items - Range 0x70 - 0x79 - This must match the number of Bonding entries #define BLE_NVID_GATT_CFG_START 0x70 //!< Start of the GATT Configuration NV IDs #define BLE_NVID_GATT_CFG_END 0x79 //!< End of the GATT Configuration NV IDs// Customer NV Items - Range 0x80 - 0x8F - This must match the number of Bonding entries #define BLE_NVID_CUST_START 0x80 //!< Start of the Customer's NV IDs #define BLE_NVID_CUST_END 0x8F //!< End of the Customer's NV IDs可見 0x80~0x8F 是用戶可以用(包含 0x80、0x8F),每個 ID 號最多一次可寫入 252 字節(jié)。
注:實際可以寫幾個 ID 取決于所剩余 SNV 空間,并不是說可以把所有 ID 號都寫滿 252字節(jié)。
1.3 工程中可選的SNV大小
可在編譯器的預(yù)編譯處寫入三種宏,不同的宏表示不同 SNV 大小:
① OSAL_SNV = 0
0 個可寫 SNV 頁。工程中不使用 SNV,由于綁定信息時需要 SNV,該操作將導(dǎo)致無法使用綁定功能。
② OSAL_SNV = 1
1 個可寫 SNV 頁,共 2K。
③ OSAL_SNV = 2(默認)
2 個可寫 SNV 頁,共 4K。
注:如果沒有在編譯器中定義 OSAL_SNV,在協(xié)議棧代碼中會自動被復(fù)制為 2,也就是默認用 4K的 SNV。
二、注意事項
1) 仿真時編譯器會擦除 flash 全片數(shù)據(jù),SNV 數(shù)據(jù)也會被擦除。
2) 寫 1K 字節(jié)到 SNV,怎么寫?
可以每個 ID 寫 252 字節(jié),一共需要 4 個 ID(1000/252=3.96)。
3) 為什么有些工程使用不了 SNV(比如組網(wǎng)的例程)?
因為組網(wǎng)例程所需 flash 較大,因此該工程的 SNV 部分被充分利用在了組網(wǎng)部分。
可以看工程的預(yù)編譯中包含了“OSAL_SNV=0”。
4) 寫 SNV 會耗時百毫秒級,盡可能在寫的時候關(guān)閉中斷。
5) 盡可能地少寫 SNV,因為它耗時耗電。
6) 如果 SNV 的存儲結(jié)構(gòu)改變,或者協(xié)議棧版本升級了,有必要重新擦除和初始化 SNV 內(nèi)存數(shù)據(jù),否則讀寫時會出錯。
7) 盡量不要把 SNV 的代碼放到中斷函數(shù)里,建議單獨弄個事件處理 SNV。
8) 一次最多只能對一個 ID 寫 252 個字節(jié),寫多時雖然返回值仍然是“SUCCESS”,但實測讀出來的數(shù)據(jù)是錯的。
三、移植文件
鏈接:https://pan.baidu.com/s/1fzlCQEthZHpK5qd3rr3JDA 提取碼:3nbv
將 snv_flash.c 和 snv_flash.h 兩個文件拖拽至CCS工程的Application文件夾下
添加文件過程中,選項選擇如下
3.1 snv_flash.c
/********************************************************************** INCLUDES*/ #include "osal_snv.h" #include "snv_flash.h"/********************************************************************** PUBLIC FUNCTIONS*//**@brief SNV讀寫內(nèi)存操作@param snvId NV頁數(shù)@param readWriteFlag 讀寫操作標(biāo)志@param pData 指向需要操作的數(shù)據(jù)@param dataLen 數(shù)據(jù)長度@return SUCCESS - 成功;FAILURE - 失敗 */ uint8 Snv_FlashContrl(uint8 snvId, uint8 readWriteFlag, uint8 *pData, uint8 dataLen) {if(readWriteFlag == SNV_READ) // 讀取數(shù)據(jù){return osal_snv_read(snvId, dataLen, pData);}else // 寫入數(shù)據(jù){return osal_snv_write(snvId, dataLen, pData);} }/*************************************END OF FILE*************************************/3.2 snv_flash.h
#ifndef _SNV_FLASH_H_ #define _SNV_FLASH_H_/********************************************************************** DEFINITIONS*/ #define SNV_READ 0x00 #define SNV_WRITE 0x01#define CUSTOM_SNV_ID 0x80 // 使用的ID,用戶可用0x80~0x8F #define CUSTOM_SNV_NUM 252 // 此ID使用到的字節(jié)數(shù)/********************************************************************** API FUNCTIONS*/ uint8 Snv_FlashContrl(uint8 snvId, uint8 readWriteFlag, uint8 *pData, uint8 dataLen);#endif /* _SNV_FLASH_H_ */四、API調(diào)用
需包含頭文件 snv_flash.h
Snv_FlashContrl
| 函數(shù)定義 | uint8 Snv_FlashContrl(uint8 snvId, uint8 readWriteFlag, uint8 *pData, uint8 dataLen) |
| 參數(shù)1 | snvId NV頁數(shù) |
| 參數(shù)2 | readWriteFlag 讀寫操作標(biāo)志 |
| 參數(shù)3 | pData 指向需要操作的數(shù)據(jù) |
| 參數(shù)4 | dataLen 數(shù)據(jù)長度 |
| 返回 | SUCCESS - 成功;FAILURE - 失敗 |
五、使用例子
1)添加頭文件(例 multi_role.c 中)
#include "snv_flash.h"2)定義一個數(shù)據(jù)緩存區(qū)(例 multi_role.c 中)
// 數(shù)據(jù)緩沖區(qū) static uint8 s_testData[256] = {0};3)添加讀取數(shù)據(jù)代碼(multi_role.c 的 multi_role_init 函數(shù)末尾中)
// 讀取保存在SNV中的數(shù)據(jù) Snv_FlashContrl(CUSTOM_SNV_ID, SNV_READ, (uint8 *)s_testData, CUSTOM_SNV_NUM);4)添加寫入數(shù)據(jù)代碼(在某個事件回調(diào)函數(shù)中)
// SNV寫入內(nèi)存 Snv_FlashContrl(CUSTOM_SNV_ID, SNV_WRITE, (uint8 *)s_testData, CUSTOM_SNV_NUM);? 由 Leung 寫于 2019 年 4 月 11 日
? 參考:【BLE-CC2640】CC2640之SNV
總結(jié)
以上是生活随笔為你收集整理的CC2640R2F学习笔记(16)——SNV Flash使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SimHash算法原理与应用(Java版
- 下一篇: S2SH+ExtJS4+Oracle9i