• 芯科蓝牙BG27开发笔记8-片上Flash读写


    目标

    熟悉片上Flash的特点,知道如何使用,最好找到示例代码,有完整例程那是最好的

    查找参考手册

    除了768K的主空间,还包含:

    1. USERDATA区域,用户定义数据,可以读写。大小只有1K。

    2. 设备特性和识别信息的DEVINFO空间

    3. 内部生产测试和校准信息的CHIPCONFIG。


    RAM有两个部分:

    RAM0:共64K,0x20000000 - 0x2000FFFF

    SEQRAM:应该是RF状态机需要的,如果不使用RF,可以用作其他。

    主flash,768K:

    最小擦除单元1页,8K大小。

    10K擦除寿命。

    查找蓝牙api.h

    目前不知道这该如何使用,暂且不考虑。

    1. /**
    2. * @addtogroup sl_bt_nvm NVM
    3. * @{
    4. *
    5. * @brief NVM
    6. *
    7. * Provide an interface to manage user data objects (key/value pairs) in the
    8. * flash memory. User data stored within the flash memory is persistent across
    9. * reset and power cycling of the device. Because Bluetooth bondings are also
    10. * stored in the flash area, in addition to the flash storage size, the space
    11. * available for user data also depends on the number of bondings the device has
    12. * at the time.
    13. *
    14. * On EFR32[B|M]G1x devices, either PS Store or NVM3 data storage driver can be
    15. * used. PS Store is supported by the Bluetooth stack only. Using NVM3 is
    16. * recommended if the device needs to support Dynamic Multiple Protocol (DMP).
    17. * On EFR32[B|M]G2x devices, only NVM3 is supported. When NVM3 is used,
    18. * applications can also use the NVM3 APIs directly.
    19. *
    20. * In PS Store, the flash storage size is fixed at 2048 bytes. The maximum data
    21. * object size associated to a key is 56 bytes. A Bluetooth bonding uses at
    22. * maximum 138 bytes for secure connections and 174 bytes for legacy pairing.
    23. *
    24. * In NVM3, the flash store size is configurable and the minimum is 3 flash
    25. * pages. The maximum data object size is configurable up to 4096 bytes. A
    26. * Bluetooth bonding uses maximum 110 bytes for secure connections and 138 bytes
    27. * for legacy pairing. For more details, see AN1135 "Using Third Generation
    28. * NonVolatile Memory (NVM3) Data Storage".
    29. */
    30. /* Command and Response IDs */
    31. #define sl_bt_cmd_nvm_save_id 0x020d0020
    32. #define sl_bt_cmd_nvm_load_id 0x030d0020
    33. #define sl_bt_cmd_nvm_erase_id 0x040d0020
    34. #define sl_bt_cmd_nvm_erase_all_id 0x010d0020
    35. #define sl_bt_rsp_nvm_save_id 0x020d0020
    36. #define sl_bt_rsp_nvm_load_id 0x030d0020
    37. #define sl_bt_rsp_nvm_erase_id 0x040d0020
    38. #define sl_bt_rsp_nvm_erase_all_id 0x010d0020
    39. /**
    40. * @addtogroup sl_bt_nvm_keys Defined Keys
    41. * @{
    42. *
    43. * Define keys
    44. */
    45. /** Crystal tuning value override */
    46. #define SL_BT_NVM_KEY_CTUNE 0x32
    47. /** @} */ // end Defined Keys
    48. /***************************************************************************//**
    49. *
    50. * Store a value into the specified NVM key. Allowed NVM keys are in range from
    51. * 0x4000 to 0x407F. At most, 56 bytes user data can be stored in one NVM key.
    52. * The error code 0x018a (command_too_long) is returned if the value data is
    53. * more than 56 bytes.
    54. *
    55. * @param[in] key NVM key
    56. * @param[in] value_len Length of data in @p value
    57. * @param[in] value Value to store into the specified NVM key
    58. *
    59. * @return SL_STATUS_OK if successful. Error code otherwise.
    60. *
    61. ******************************************************************************/
    62. sl_status_t sl_bt_nvm_save(uint16_t key,
    63. size_t value_len,
    64. const uint8_t* value);
    65. /***************************************************************************//**
    66. *
    67. * Retrieve the value of the specified NVM key.
    68. *
    69. * @param[in] key NVM key of the value to be retrieved
    70. * @param[in] max_value_size Size of output buffer passed in @p value
    71. * @param[out] value_len On return, set to the length of output data written to
    72. * @p value
    73. * @param[out] value The returned value of the specified NVM key
    74. *
    75. * @return SL_STATUS_OK if successful. Error code otherwise.
    76. *
    77. ******************************************************************************/
    78. sl_status_t sl_bt_nvm_load(uint16_t key,
    79. size_t max_value_size,
    80. size_t *value_len,
    81. uint8_t *value);
    82. /***************************************************************************//**
    83. *
    84. * Delete a single NVM key and its value from the persistent store.
    85. *
    86. * @param[in] key NVM key to delete
    87. *
    88. * @return SL_STATUS_OK if successful. Error code otherwise.
    89. *
    90. ******************************************************************************/
    91. sl_status_t sl_bt_nvm_erase(uint16_t key);
    92. /***************************************************************************//**
    93. *
    94. * Delete all NVM keys and their corresponding values.
    95. *
    96. *
    97. * @return SL_STATUS_OK if successful. Error code otherwise.
    98. *
    99. ******************************************************************************/
    100. sl_status_t sl_bt_nvm_erase_all();
    101. /** @} */ // 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中也有少量代码(代码中新建了操作句柄,实际上直接使用默认句柄更易于入门,直接参考下文例程app中的内容即可):

    1. 【Example 1 shows initialization, usage of data objects and repacking.】
    2. #include "nvm3.h"
    3. #include "nvm3_hal_flash.h"
    4. // Create a NVM area of 24kB (size must equal N * FLASH_PAGE_SIZE, N is integer). Create a cache of 10 entries.
    5. NVM3_DEFINE_SECTION_STATIC_DATA(nvm3Data1, 24576, 10);
    6. // This macro creates the following:
    7. // 1. An array to hold NVM data named nvm3Data1_nvm
    8. // 2. A section called nvm3Data1_section containing nvm3Data1_nvm. The application linker script must place this section correctly in memory.
    9. // 3. A cache array: nvm3Data1_cache
    10. void nvm3_example_1(void)
    11. {
    12. // Declare a nvm3_Init_t struct of name nvm3Data1 with initialization data. This is passed to nvm3_open() below.
    13. NVM3_DEFINE_SECTION_INIT_DATA(nvm3Data1, &nvm3_halFlashHandle);
    14. nvm3_Handle_t handle;
    15. Ecode_t status;
    16. size_t numberOfObjects;
    17. unsigned char data1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    18. unsigned char data2[] = { 11, 12, 13, 14, 15 };
    19. uint32_t objectType;
    20. size_t dataLen1;
    21. size_t dataLen2;
    22. status = nvm3_open(&handle, &nvm3Data1);
    23. if (status != ECODE_NVM3_OK) {
    24. // Handle error
    25. }
    26. // Get the number of valid keys already in NVM3
    27. numberOfObjects = nvm3_countObjects(&handle);
    28. // Skip if we have initial keys. If not, generate objects and store
    29. // persistently in NVM3 before proceeding.
    30. if (numberOfObjects < 2) {
    31. // Erase all objects and write initial data to NVM3
    32. nvm3_eraseAll(&handle);
    33. nvm3_writeData(&handle, 1, data1, sizeof(data1));
    34. nvm3_writeData(&handle, 2, data2, sizeof(data2));
    35. }
    36. // Find size of data for object with key identifier 1 and 2 and read out
    37. nvm3_getObjectInfo(&handle, 1, &objectType, &dataLen1);
    38. if (objectType == NVM3_OBJECTTYPE_DATA) {
    39. nvm3_readData(&handle, 1, data1, dataLen1);
    40. }
    41. nvm3_getObjectInfo(&handle, 2, &objectType, &dataLen2);
    42. if (objectType == NVM3_OBJECTTYPE_DATA) {
    43. nvm3_readData(&handle, 2, data2, dataLen2);
    44. }
    45. // Update and write back data
    46. data1[0]++;
    47. data2[0]++;
    48. nvm3_writeData(&handle, 1, data1, dataLen1);
    49. nvm3_writeData(&handle, 2, data2, dataLen2);
    50. // Do repacking if needed
    51. if (nvm3_repackNeeded(&handle)) {
    52. status = nvm3_repack(&handle);
    53. if (status != ECODE_NVM3_OK) {
    54. // Handle error
    55. }
    56. }
    57. }
    58. 【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.】
    59. #include "nvm3.h"
    60. #include "nvm3_hal_flash.h"
    61. // Create a NVM area of 24kB (size must equal N * FLASH_PAGE_SIZE, N is integer). Create a cache of 10 entries.
    62. NVM3_DEFINE_SECTION_STATIC_DATA(nvm3Data2, 24576, 10);
    63. #define USER_KEY 1
    64. // This macro creates the following:
    65. // 1. An array to hold NVM data named nvm3Data2_nvm
    66. // 2. A section called nvm3Data2_section containing nvm3Data2_nvm. The application linker script must place this section correctly in memory.
    67. // 3. A cache array: nvm3Data2_cache
    68. void nvm3_example_2(void)
    69. {
    70. // Declare a nvm3_Init_t struct of name nvm3Data2 with initialization data. This is passed to nvm3_open() below.
    71. NVM3_DEFINE_SECTION_INIT_DATA(nvm3Data2, &nvm3_halFlashHandle);
    72. nvm3_Handle_t handle;
    73. Ecode_t status;
    74. uint32_t counter = 1;
    75. status = nvm3_open(&handle, &nvm3Data2);
    76. if (status != ECODE_NVM3_OK) {
    77. // Handle error
    78. }
    79. // Erase all objects
    80. nvm3_eraseAll(&handle);
    81. // Write first counter value with key 1
    82. nvm3_writeCounter(&handle, USER_KEY, counter);
    83. // Increment the counter by 1 without reading out the updated value
    84. nvm3_incrementCounter(&handle, USER_KEY, NULL);
    85. // Read the counter value
    86. nvm3_readCounter(&handle, USER_KEY, &counter);
    87. }

    找到现成的示例

    可以通过检索关键词来查找使用到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

    在蓝牙例程文件夹检索关键词,选定蓝牙温控器这个例程继续阅读:

    nvm3资料汇总

    参考三份资料:

    NVM3 - NVM Data Manager - v3.1 - Gecko Platform API Documentation Silicon Labs

    《ug103-07-non-volatile-data-storage-fundamentals.pdf》

    《an1135-using-third-generation-nonvolatile-memory.pdf》

    《nvm3_generic.h》末尾文档,与第一个在线文档类似

    补充资料

    SDK的API文档:

    Gecko Platform - v3.1 - Gecko Platform API Documentation Silicon Labs

    蓝牙协议栈API文档:

    General Overview - v4.0 - Bluetooth API Documentation Silicon Labs

    这两份文档内容很多,也很系统,有助于理解一些基本的概念。

    【增补.2023.12】

    BG27一个page8K,nvm最小需要3page,默认的flash排布在768k的末尾。

    查看链接文件.ld和map文件,结果与上图对应。最后一个page被空出。

  • 相关阅读:
    【设计模式-04】原型模式
    【MAVEN依赖冲突如何解决】
    固有频率约束下桁架优化的动态算术优化算法(Matlab代码实现)
    C/C++语言100题练习计划 90——10 进制转 x 进制(进制转换实现)
    三十九、Fluent时间步长的估算与库朗数
    【车载测试专项】 整车控制器 逻辑时序测试
    08-分布式
    【IEEE会议征稿通知】第五届计算机视觉、图像与深度学习国际学术会议(CVIDL 2024)
    答辩提纲的写作内容指导
    小程序制作(超详解!!!)第十三节 随机数求和
  • 原文地址:https://blog.csdn.net/hxkrrzq/article/details/132897030