目标
熟悉片上Flash的特点,知道如何使用,最好找到示例代码,有完整例程那是最好的
查找参考手册
除了768K的主空间,还包含:
1. USERDATA区域,用户定义数据,可以读写。大小只有1K。
2. 设备特性和识别信息的DEVINFO空间
3. 内部生产测试和校准信息的CHIPCONFIG。
RAM有两个部分:
RAM0:共64K,0x20000000 - 0x2000FFFF
SEQRAM:应该是RF状态机需要的,如果不使用RF,可以用作其他。
主flash,768K:
最小擦除单元1页,8K大小。
10K擦除寿命。
查找蓝牙api.h
目前不知道这该如何使用,暂且不考虑。
/**
* @addtogroup sl_bt_nvm NVM
* @{
*
* @brief NVM
*
* Provide an interface to manage user data objects (key/value pairs) in the
* flash memory. User data stored within the flash memory is persistent across
* reset and power cycling of the device. Because Bluetooth bondings are also
* stored in the flash area, in addition to the flash storage size, the space
* available for user data also depends on the number of bondings the device has
* at the time.
*
* On EFR32[B|M]G1x devices, either PS Store or NVM3 data storage driver can be
* used. PS Store is supported by the Bluetooth stack only. Using NVM3 is
* recommended if the device needs to support Dynamic Multiple Protocol (DMP).
* On EFR32[B|M]G2x devices, only NVM3 is supported. When NVM3 is used,
* applications can also use the NVM3 APIs directly.
*
* In PS Store, the flash storage size is fixed at 2048 bytes. The maximum data
* object size associated to a key is 56 bytes. A Bluetooth bonding uses at
* maximum 138 bytes for secure connections and 174 bytes for legacy pairing.
*
* In NVM3, the flash store size is configurable and the minimum is 3 flash
* pages. The maximum data object size is configurable up to 4096 bytes. A
* Bluetooth bonding uses maximum 110 bytes for secure connections and 138 bytes
* for legacy pairing. For more details, see AN1135 "Using Third Generation
* NonVolatile Memory (NVM3) Data Storage".
*/
/* Command and Response IDs */
#define sl_bt_cmd_nvm_save_id 0x020d0020
#define sl_bt_cmd_nvm_load_id 0x030d0020
#define sl_bt_cmd_nvm_erase_id 0x040d0020
#define sl_bt_cmd_nvm_erase_all_id 0x010d0020
#define sl_bt_rsp_nvm_save_id 0x020d0020
#define sl_bt_rsp_nvm_load_id 0x030d0020
#define sl_bt_rsp_nvm_erase_id 0x040d0020
#define sl_bt_rsp_nvm_erase_all_id 0x010d0020
/**
* @addtogroup sl_bt_nvm_keys Defined Keys
* @{
*
* Define keys
*/
/** Crystal tuning value override */
#define SL_BT_NVM_KEY_CTUNE 0x32
/** @} */ // end Defined Keys
/***************************************************************************//**
*
* Store a value into the specified NVM key. Allowed NVM keys are in range from
* 0x4000 to 0x407F. At most, 56 bytes user data can be stored in one NVM key.
* The error code 0x018a (command_too_long) is returned if the value data is
* more than 56 bytes.
*
* @param[in] key NVM key
* @param[in] value_len Length of data in @p value
* @param[in] value Value to store into the specified NVM key
*
* @return SL_STATUS_OK if successful. Error code otherwise.
*
******************************************************************************/
sl_status_t sl_bt_nvm_save(uint16_t key,
size_t value_len,
const uint8_t* value);
/***************************************************************************//**
*
* Retrieve the value of the specified NVM key.
*
* @param[in] key NVM key of the value to be retrieved
* @param[in] max_value_size Size of output buffer passed in @p value
* @param[out] value_len On return, set to the length of output data written to
* @p value
* @param[out] value The returned value of the specified NVM key
*
* @return SL_STATUS_OK if successful. Error code otherwise.
*
******************************************************************************/
sl_status_t sl_bt_nvm_load(uint16_t key,
size_t max_value_size,
size_t *value_len,
uint8_t *value);
/***************************************************************************//**
*
* Delete a single NVM key and its value from the persistent store.
*
* @param[in] key NVM key to delete
*
* @return SL_STATUS_OK if successful. Error code otherwise.
*
******************************************************************************/
sl_status_t sl_bt_nvm_erase(uint16_t key);
/***************************************************************************//**
*
* Delete all NVM keys and their corresponding values.
*
*
* @return SL_STATUS_OK if successful. Error code otherwise.
*
******************************************************************************/
sl_status_t sl_bt_nvm_erase_all();
/** @} */ // end addtogroup sl_bt_nvm
在ssv5的文档中搜索“flash”:
找到两篇文档:
ug103-07-non-volatile-data-storage-fundamentals-断电存储
an1135-using-third-generation-nonvolatile-memory-NVM3使用方法
上图有多个flash操作库,但是BG27只能选择NVM3。如何使用NVM3在文档中有说明,不过为什么就没有一个简单的例程直接开箱即用呢???
查阅文档:
NVM3 - NVM Data Manager - v3.1 - Gecko Platform API Documentation Silicon Labs
结合A1115文档阅读;
以上文档说明已很充足,上图examples中也有少量代码:
【Example 1 shows initialization, usage of data objects and repacking.】
#include "nvm3.h"
#include "nvm3_hal_flash.h"
// Create a NVM area of 24kB (size must equal N * FLASH_PAGE_SIZE, N is integer). Create a cache of 10 entries.
NVM3_DEFINE_SECTION_STATIC_DATA(nvm3Data1, 24576, 10);
// This macro creates the following:
// 1. An array to hold NVM data named nvm3Data1_nvm
// 2. A section called nvm3Data1_section containing nvm3Data1_nvm. The application linker script must place this section correctly in memory.
// 3. A cache array: nvm3Data1_cache
void nvm3_example_1(void)
{
// Declare a nvm3_Init_t struct of name nvm3Data1 with initialization data. This is passed to nvm3_open() below.
NVM3_DEFINE_SECTION_INIT_DATA(nvm3Data1, &nvm3_halFlashHandle);
nvm3_Handle_t handle;
Ecode_t status;
size_t numberOfObjects;
unsigned char data1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
unsigned char data2[] = { 11, 12, 13, 14, 15 };
uint32_t objectType;
size_t dataLen1;
size_t dataLen2;
status = nvm3_open(&handle, &nvm3Data1);
if (status != ECODE_NVM3_OK) {
// Handle error
}
// Get the number of valid keys already in NVM3
numberOfObjects = nvm3_countObjects(&handle);
// Skip if we have initial keys. If not, generate objects and store
// persistently in NVM3 before proceeding.
if (numberOfObjects < 2) {
// Erase all objects and write initial data to NVM3
nvm3_eraseAll(&handle);
nvm3_writeData(&handle, 1, data1, sizeof(data1));
nvm3_writeData(&handle, 2, data2, sizeof(data2));
}
// Find size of data for object with key identifier 1 and 2 and read out
nvm3_getObjectInfo(&handle, 1, &objectType, &dataLen1);
if (objectType == NVM3_OBJECTTYPE_DATA) {
nvm3_readData(&handle, 1, data1, dataLen1);
}
nvm3_getObjectInfo(&handle, 2, &objectType, &dataLen2);
if (objectType == NVM3_OBJECTTYPE_DATA) {
nvm3_readData(&handle, 2, data2, dataLen2);
}
// Update and write back data
data1[0]++;
data2[0]++;
nvm3_writeData(&handle, 1, data1, dataLen1);
nvm3_writeData(&handle, 2, data2, dataLen2);
// Do repacking if needed
if (nvm3_repackNeeded(&handle)) {
status = nvm3_repack(&handle);
if (status != ECODE_NVM3_OK) {
// Handle error
}
}
}
【Example 2 shows initialization and usage of counter objects. The counter object uses a compact way of storing a 32-bit counter value while minimizing NVM wear.】
#include "nvm3.h"
#include "nvm3_hal_flash.h"
// Create a NVM area of 24kB (size must equal N * FLASH_PAGE_SIZE, N is integer). Create a cache of 10 entries.
NVM3_DEFINE_SECTION_STATIC_DATA(nvm3Data2, 24576, 10);
#define USER_KEY 1
// This macro creates the following:
// 1. An array to hold NVM data named nvm3Data2_nvm
// 2. A section called nvm3Data2_section containing nvm3Data2_nvm. The application linker script must place this section correctly in memory.
// 3. A cache array: nvm3Data2_cache
void nvm3_example_2(void)
{
// Declare a nvm3_Init_t struct of name nvm3Data2 with initialization data. This is passed to nvm3_open() below.
NVM3_DEFINE_SECTION_INIT_DATA(nvm3Data2, &nvm3_halFlashHandle);
nvm3_Handle_t handle;
Ecode_t status;
uint32_t counter = 1;
status = nvm3_open(&handle, &nvm3Data2);
if (status != ECODE_NVM3_OK) {
// Handle error
}
// Erase all objects
nvm3_eraseAll(&handle);
// Write first counter value with key 1
nvm3_writeCounter(&handle, USER_KEY, counter);
// Increment the counter by 1 without reading out the updated value
nvm3_incrementCounter(&handle, USER_KEY, NULL);
// Read the counter value
nvm3_readCounter(&handle, USER_KEY, &counter);
}
找到现成的示例
可以通过检索关键词来查找使用到nvm3接口的代码,是否有一个完整例程存在?
检索词可以用,nvm3_open,nvm3_readData
但是前提是,要有例程源码存在。
一般情况,如nordic,提供了例程包,例程分为两部分:
1. 裸机例程
2. 蓝牙应用例程
在此之前,我认为芯科的例程是在ssv5 IDE中,需要自己创建才会自动生成;还有技术支持(第三方)发了一个裸机驱动包,这个我知道都是芯科官方github上有的。
经过查找,参考本帖《补充资料》,可知两个包的地址:
GitHub - SiliconLabs/bluetooth_applications: Bluetooth wireless applications. Go to https://github.com/SiliconLabs/application_examples
GitHub - SiliconLabs/peripheral_examples: Simple peripheral examples for Silicon Labs EFM32/EFR32 Series 0, Series 1, and Series 2 devices
在蓝牙例程文件夹检索关键词,选定蓝牙温控器这个例程继续阅读:
补充资料
SDK的API文档:
Gecko Platform - v3.1 - Gecko Platform API Documentation Silicon Labs
蓝牙协议栈API文档:
General Overview - v4.0 - Bluetooth API Documentation Silicon Labs
这两份文档内容很多,也很系统,有助于理解一些基本的概念。