本篇博文最后修改时间:2017年06月02日,06:40。
一、简介
本文以SimpleBLEPeripheral工程为例,介绍如何使用SNV。
二、实验平台
协议栈版本:ble_cc26xx_2_01_00_44423
编译软件:IAR Embedded Workbench for ARM Version 7.40
硬件平台:CC26xxDK开发板
仿真器:XDS100V3(香瓜)
三、版权声明
博主:甜甜的大香瓜
声明:喝水不忘挖井人,转载请注明出处。
原文地址:http://blog.csdn.NET/feilusia
联系方式:897503845@qq.com
香瓜BLE之CC2541群:127442605
香瓜BLE之CC2640群:557278427
香瓜单片机之职场交流群:450154342
暂无
五、基础知识
1、CC2640的SNV是怎么样的?
答:
1)总大小
两页,共4K(协议栈已使用一部分)。
2)可用SNV的ID号
// 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字节。
3)工程中可选的SNV大小
可在IAR的预编译处写入三种宏:
①OSAL_SNV=0:0个可写SNV页。工程中不使用SNV,由于绑定信息时需要SNV,该操作将导致无法使用绑定功能。
②OSAL_SNV=1:1个可写SNV页,共2K。
③OSAL_SNV=2(默认):2个可写SNV页,共4K。
2、多次“仿真、退出仿真、仿真”的操作,是否会把SNV擦除?
答:实测不会。
注:CC2541使用仿真时会擦除SNV。
3、如果我想写1K字节到SNV,怎么写?
答:可以每个ID写252字节,一共需要4个ID(1000/252=3.96)。
4、为什么有些工程使用不了SNV(比如组网的例程)?
答:因为组网例程所需flash较大,因此该工程的SNV部分被充分利用在了组网部分。
可以看工程的预编译中包含了“OSAL_SNV=0”。
六、实验步骤
1、编写并添加自定义的SNV驱动
1)写一个驱动GUA_SNV.c(存放在“……\ble_cc26xx_2_01_00_44423\Projects\ble\SimpleBLEPeripheral\CC26xx\Source\Application\GUA”路径下)
//******************************************************************************
//name: GUA_SNV.c
//introduce: SNV驱动
//author: 甜甜的大香瓜
//email: 897503845@qq.com
//QQ group 香瓜BLE之CC2640(557278427)
//changetime: 2017.02.26
//******************************************************************************
#include "GUA_SNV.h"
#include "osal_snv.h"
//******************************************************************************
//name: GUA_SNV_Control
//introduce: SNV的读写操作函数
//parameter: nGUA_WriteReadFlag:GUA_SNV_READ or GUA_SNV_WRITE
// npGUA_Data:数据首地址
// nGUA_Len:数据长度
//return: none
//author: 甜甜的大香瓜
//email: 897503845@qq.com
//QQ group 香瓜BLE之CC2640(557278427)
//changetime: 2017.02.26
//******************************************************************************
GUA_U8 GUA_SNV_Control(GUA_U8 nGUA_SNV_ID, GUA_U8 nGUA_WriteReadFlag, GUA_U8 *npGUA_Data, GUA_U8 nGUA_Len)
{
//读数据
if(nGUA_WriteReadFlag == GUA_SNV_READ)
{
return osal_snv_read(nGUA_SNV_ID, nGUA_Len, npGUA_Data);
}
//写数据
else
{
return osal_snv_write(nGUA_SNV_ID, nGUA_Len, npGUA_Data);
}
}
2)写一个驱动头文件GUA_SNV.h(存放在“……\ble_cc26xx_2_01_00_44423\Projects\ble\SimpleBLEPeripheral\CC26xx\Source\Application\GUA”路径下)
//******************************************************************************
//name: GUA_SNV.c
//introduce: SNV驱动头文件
//author: 甜甜的大香瓜
//email: 897503845@qq.com
//QQ group 香瓜BLE之CC2640(557278427)
//changetime: 2017.02.26
//******************************************************************************
#ifndef _GUA_SNV_H_
#define _GUA_SNV_H_
/*********************宏定义************************/
#ifndef GUA_U8
typedef unsigned char GUA_U8;
#endif
#ifndef GUA_8
typedef signed char GUA_8;
#endif
#ifndef GUA_U16
typedef unsigned short GUA_U16;
#endif
#ifndef GUA_16
typedef signed short GUA_16;
#endif
#ifndef GUA_U32
typedef unsigned long GUA_U32;
#endif
#ifndef GUA_32
typedef signed long GUA_32;
#endif
#ifndef GUA_U64
typedef unsigned long long GUA_U64;
#endif
#ifndef GUA_64
typedef signed long long GUA_64;
#endif
//SNV使用宏
#define GUA_SNV_READ 0x00
#define GUA_SNV_WRITE 0x01
/*********************外部函数************************/
GUA_U8 GUA_SNV_Control(GUA_U8 nGUA_SNV_ID, GUA_U8 nGUA_WriteReadFlag, GUA_U8 *npGUA_Data, GUA_U8 nGUA_Len);
#endif
3)工程中添加GUA_SNV.c
$PROJ_DIR$/../../../Source/Application/GUA
2、应用层调用
1)添加头文件(simpleBLEperipheral.c中)
#include "GUA_SNV.h"
//数据缓冲区
static uint8_t gbGUA_Data[256] = {0};
//SNV使用宏
#define GUA_SNV_TEST_ID 0x81
4)添加测试代码 (simpleBLEPeripheral.c的SimpleBLEPeripheral_Init函数末尾)
//GUA
uint8_t nGUA_Ret = 0;
//读
nGUA_Ret = GUA_SNV_Control(GUA_SNV_TEST_ID, GUA_SNV_READ, gbGUA_Data, 252);
if(nGUA_Ret == NV_OPER_FAILED)
{
//设置缓冲区数值
memset(gbGUA_Data, 0x38, sizeof(gbGUA_Data));
//出厂设置
nGUA_Ret = GUA_SNV_Control(GUA_SNV_TEST_ID, GUA_SNV_WRITE, gbGUA_Data, 252);
}
//写
memset(gbGUA_Data, 0x55, sizeof(gbGUA_Data));
nGUA_Ret = GUA_SNV_Control(GUA_SNV_TEST_ID, GUA_SNV_WRITE, gbGUA_Data, 252);
//读
memset(gbGUA_Data, 0x00, sizeof(gbGUA_Data));
nGUA_Ret = GUA_SNV_Control(GUA_SNV_TEST_ID, GUA_SNV_READ, gbGUA_Data, 252);
//GUA
暂无。
八、实验结果
测试可发现如下现象:
1、当该ID之前未写过数据时,读取的返回值为“NV_OPER_FAILED”。
2、一次最多只能对一个ID写252个字节,写多时虽然返回值仍然是“SUCCESS”,但实测读出来的数据是错的。
3、再次仿真时不会将上次写入的SNV数据擦除。
因此,实验成功。