轉自:http://blog.csdn.net/feilusia/article/details/57374684
一、簡介
本文以SimpleBLEPeripheral工程爲例,介紹如何使用SNV。
二、實驗平臺
協議棧版本:ble_cc26xx_2_01_00_44423
編譯軟件:IAR Embedded Workbench for ARM Version 7.40
硬件平臺:CC26xxDK開發板
仿真器:XDS100V3(香瓜)
暫無
五、基礎知識
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
注:實際可以寫幾個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: [email protected]
- //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: [email protected]
- //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: [email protected]
- //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數據擦除。
因此,實驗成功。