CC2640R2F学习笔记(16)——SNV Flash使用

一、背景

SNV(Simple Non-Volatile,简单的非易挥发),是从内部 flash 末尾划分大约 1~4K大小的一块专用于存储数据的存储空间。一般用于存储协议栈必要的存储数据、用户的应用数据。类似于 STM32 的片内 EEPROM。

NV(Non-Volatile,非易挥发) 是 16 位 ID,而 SNV 是简化版的 NV 只有 8 位 ID。

1.1 SNV大小

两页,共 4K(协议栈已使用一部分)。

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 字节。

注:实际可以写几个 ID 取决于所剩余 SNV 空间,并不是说可以把所有 ID 号都写满 252字节。

1.3 工程中可选的SNV大小

可在编译器的预编译处写入三种宏,不同的宏表示不同 SNV 大小:
① OSAL_SNV = 0
0 个可写 SNV 页。工程中不使用 SNV,由于绑定信息时需要 SNV,该操作将导致无法使用绑定功能。
② OSAL_SNV = 1
1 个可写 SNV 页,共 2K。
③ OSAL_SNV = 2(默认)
2 个可写 SNV 页,共 4K。

注:如果没有在编译器中定义 OSAL_SNV,在协议栈代码中会自动被复制为 2,也就是默认用 4K的 SNV。

二、注意事项

1) 仿真时编译器会擦除 flash 全片数据,SNV 数据也会被擦除。
2) 写 1K 字节到 SNV,怎么写?
可以每个 ID 写 252 字节,一共需要 4 个 ID(1000/252=3.96)。
3) 为什么有些工程使用不了 SNV(比如组网的例程)?
因为组网例程所需 flash 较大,因此该工程的 SNV 部分被充分利用在了组网部分。
可以看工程的预编译中包含了“OSAL_SNV=0”。
4) 写 SNV 会耗时百毫秒级,尽可能在写的时候关闭中断。
5) 尽可能地少写 SNV,因为它耗时耗电。
6) 如果 SNV 的存储结构改变,或者协议栈版本升级了,有必要重新擦除和初始化 SNV 内存数据,否则读写时会出错。
7) 尽量不要把 SNV 的代码放到中断函数里,建议单独弄个事件处理 SNV。
8) 一次最多只能对一个 ID 写 252 个字节,写多时虽然返回值仍然是“SUCCESS”,但实测读出来的数据是错的。

三、移植文件

链接:https://pan.baidu.com/s/1fzlCQEthZHpK5qd3rr3JDA 提取码:3nbv
snv_flash.csnv_flash.h 两个文件拖拽至CCS工程的Application文件夹下


添加文件过程中,选项选择如下

3.1 snv_flash.c

/*********************************************************************
 * INCLUDES
 */
#include "osal_snv.h"
#include "snv_flash.h"

/*********************************************************************
 * PUBLIC FUNCTIONS
 */

/**
 @brief SNV读写内存操作
 @param snvId NV页数
 @param readWriteFlag 读写操作标志
 @param pData 指向需要操作的数据
 @param dataLen 数据长度
 @return SUCCESS - 成功;FAILURE - 失败
*/
uint8 Snv_FlashContrl(uint8 snvId, uint8 readWriteFlag, uint8 *pData, uint8 dataLen)
{
    if(readWriteFlag == SNV_READ)                       // 读取数据
    {
        return osal_snv_read(snvId, dataLen, pData);
    }
    else                                                // 写入数据
    {
        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使用到的字节数

/*********************************************************************
 * API FUNCTIONS
 */
uint8 Snv_FlashContrl(uint8 snvId, uint8 readWriteFlag, uint8 *pData, uint8 dataLen);

#endif /* _SNV_FLASH_H_ */

四、API调用

需包含头文件 snv_flash.h

Snv_FlashContrl

功能 SNV读写内存操作
函数定义 uint8 Snv_FlashContrl(uint8 snvId, uint8 readWriteFlag, uint8 *pData, uint8 dataLen)
参数1 snvId NV页数
参数2 readWriteFlag 读写操作标志
参数3 pData 指向需要操作的数据
参数4 dataLen 数据长度
返回 SUCCESS - 成功;FAILURE - 失败

五、使用例子

1)添加头文件(例 multi_role.c 中)

#include "snv_flash.h"

2)定义一个数据缓存区(例 multi_role.c 中)

// 数据缓冲区
static uint8 s_testData[256] = {0};

3)添加读取数据代码(multi_role.c 的 multi_role_init 函数末尾中)

// 读取保存在SNV中的数据
Snv_FlashContrl(CUSTOM_SNV_ID, SNV_READ, (uint8 *)s_testData, CUSTOM_SNV_NUM);

4)添加写入数据代码(在某个事件回调函数中)

// SNV写入内存
Snv_FlashContrl(CUSTOM_SNV_ID, SNV_WRITE, (uint8 *)s_testData, CUSTOM_SNV_NUM);                            

• 由 Leung 写于 2019 年 4 月 11 日

• 参考:【BLE-CC2640】CC2640之SNV

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342