Storing user data to flash and avoiding overwrite on application update

I made an example based on the NVS sample code (Connect SDK 2.2.0) which simply reads a value from the storage partition if it exists, then updates it if either it's different than a specific value or it didn't exist in the first place. That works great.

But what I noticed is that, at least using Visual Studio Code, when I flash a new application (or even the same application) it clears the data in the storage partition, which I did not expect. So my question is about the best practice in using the NVS module for storage of device specific parameters for deployment.

The objective is that I would like to have a set of configuration parameters stored in the flash of specific devices that store some parameters (e.g., BLE name, IMU calibration, etc) that can be read in through the NVS module and won't get overwritten by a firmware flash. (The less-than-desirable alternative is an easy way to define an NVS-readable storage hex that can be merged in the flash, per-device). My original thought is that I could simply flash an application to set the flash parameters "permanently" (they don't change even with firmware updates) then flash my application, but as mentioned this doesn't work at least through the default VSCode workflow.

I've read a few mentions in passing on the forums of others indicating adding a device-specific hex file to be merged in whenever flashed. This is definitely less desirable because it doesn't seem obviously supported through VSCode in any way, it'll be more cumbersome to keep track of which calibration files to merge when flashing multiple devices, and there's no immediately obvious way I see to take advantage of the NVS storage format in a custom-spun hex dump.

Does anyone have recommendations on a reasonable way to handle this use case?

Parents
  • Hi Anthony, 


    Which sample are you testing with ? 

    By default if you click on the flash icon with one arrow (Flash only), it will only erase the sectors occupied by the new application, not the whole flash. So the NVS storage area shouldn't be affected.

    If you click on the flash icon with 2 arrows (Erase and Flash) it will erase the whole flash and then flash the application image. 

    However if you use the NVS, there is a setting in CmakeLists.txt that apply erase in both cases: 

    # SPDX-License-Identifier: Apache-2.0
    
    cmake_minimum_required(VERSION 3.20.0)
    
    macro(app_set_runner_args)
      board_runner_args(dfu-util "--dfuse-modifiers=force:mass-erase")
      board_runner_args(pyocd "--erase")
      board_runner_args(nrfjprog "--erase")
    endmacro()
    
    find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
    project(nvs)
    
    
    target_sources(app PRIVATE src/main.c)
    target_include_directories(app PRIVATE ${ZEPHYR_BASE}/subsys/fs/nvs)

    If you remove the macro that do --erase it should work fine. 

    You can also test using nrfjprog.exe command line tool. Do a --sectorerase when programming will not make the NVS data to be erased. 

Reply
  • Hi Anthony, 


    Which sample are you testing with ? 

    By default if you click on the flash icon with one arrow (Flash only), it will only erase the sectors occupied by the new application, not the whole flash. So the NVS storage area shouldn't be affected.

    If you click on the flash icon with 2 arrows (Erase and Flash) it will erase the whole flash and then flash the application image. 

    However if you use the NVS, there is a setting in CmakeLists.txt that apply erase in both cases: 

    # SPDX-License-Identifier: Apache-2.0
    
    cmake_minimum_required(VERSION 3.20.0)
    
    macro(app_set_runner_args)
      board_runner_args(dfu-util "--dfuse-modifiers=force:mass-erase")
      board_runner_args(pyocd "--erase")
      board_runner_args(nrfjprog "--erase")
    endmacro()
    
    find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
    project(nvs)
    
    
    target_sources(app PRIVATE src/main.c)
    target_include_directories(app PRIVATE ${ZEPHYR_BASE}/subsys/fs/nvs)

    If you remove the macro that do --erase it should work fine. 

    You can also test using nrfjprog.exe command line tool. Do a --sectorerase when programming will not make the NVS data to be erased. 

Children
Related