This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Problem to read back flash with NVS when concurrent use with Bluetooth

Hi,

We need to save 3 strings to flash using NVS. Based on the code sample in zephyr\samples\subsys\nvs we set the initialization and then write and read these data.

To have successful read back we need to make some dummy write to NVS before, else the reading doesn't correspond to the previous written value.

We have done the following observation:

  • doing read/write of the NVS before enabling Bluetooth works fine
  • doing read/write after enabling Bluetooth retrieves the very first data instead of the last written (and some more strange behaviour)
  • the Bluetooth stack is doing a second nvs_init() with larger sector number to fs structure

Our question are the following

  • is there more documentation on NVS than the basic developer source ?
  • is there any precautions to use "custom" access to NVS at the same time as Bluetooth stack ?
  • should we split the storage area for each uses or ID's should be fully managed by Bluetooth stack without any problems ?

We initiate fs with DTS flash controller definition (ex: nRF52833 -> storage begin at 0x7a000)

Config is NCS 1.5.0 or 1.6.0, nRF52840DK

Best regards,

Romain

Parents
  • I tried to reproduce this issue but was not able to, can you test the attached sample with NCS v1.6.0 and check if you get the same output:

    *** Booting Zephyr OS build v2.6.0-rc1-ncs1  ***
    Before nvs_init() from app
    Enable bluetooth sucess!
    Item at id 1 was found: data1
    Item at id 2 was found: data2
    Item at id 3 was found: data3
    > fs_nvs.nvs_recover_last_ate: Recovering last ate from sector 0
    [00:00:00.013,549] <inf> fs_nvs: 3 Sectors of 4096 bytes
    [00:00:00.013,549] <inf> fs_nvs: alloc wra: 0, ff0
    [00:00:00.013,549] <inf> fs_nvs: data wra: 0, 0
    [00:00:00.017,303] <dbg> fs_nvs.nvs_recover_last_ate: Recovering last ate from sector 0
    [00:00:00.022,796] <inf> fs_nvs: 8 Sectors of 4096 bytes
    [00:00:00.022,827] <inf> fs_nvs: alloc wra: 0, ff0
    [00:00:00.022,827] <inf> fs_nvs: data wra: 0, 0
    [00:00:00.022,918] <inf> sdc_hci_driver: SoftDevice Controller build revision:
                                             58 5d 8b 31 54 67 00 e9  b8 4a a7 df a9 9c e4 1c |X].1Tg.. .J......
                                             b3 0b ce 74                                      |...t
    [00:00:00.024,688] <inf> bt_hci_core: No ID address. App must call settings_load()
    

    nvs_and_ble.zip

    If I have misunderstood your issue, please attach a sample that demonstrates it.

    Best regards,

    Simon

  • Hi Simon,

    Yes I got (almost) the same log except that

    • I had to add CONFIG_LOG_PRINTK=y in proj.conf
    • The order of printk messages is not the same (due to priority level ?)

    *** Booting Zephyr OS build v2.6.0-rc1-ncs1  ***
    Before nvs_init() from app
    [00:00:10.525,390] <dbg> fs_nvs.nvs_recover_last_ate: Recovering last ate from sector 0
    [00:00:10.530,975] <inf> fs_nvs: 3 Sectors of 4096 bytes
    [00:00:10.530,975] <inf> fs_nvs: alloc wra: 0, ff0
    [00:00:10.530,975] <inf> fs_nvs: data wra: 0, 0
    [00:00:10.531,280] <dbg> fs_nvs.nvs_recover_last_ate: Recovering last ate from sector 0
    [00:00:10.536,804] <inf> fs_nvs: 8 Sectors of 4096 bytes
    [00:00:10.536,804] <inf> fs_nvs: alloc wra: 0, ff0
    [00:00:10.536,834] <inf> fs_nvs: data wra: 0, 0
    [00:00:10.536,926] <inf> sdc_hci_driver: SoftDevice Controller build revision: 
                                             58 5d 8b 31 54 67 00 e9  b8 4a a7 df a9 9c e4 1c |X].1Tg.. .J......
                                             b3 0b ce 74                                      |...t             
    [00:00:10.538,604] <inf> bt_hci_core: No ID address. App must call settings_load()
    Enable bluetooth sucess!
    Item at id 1 was found: data1
    Item at id 2 was found: data2
    Item at id 3 was found: data3

    I will try to expose some code to reproduce our issue...

    Basically we are doing the following

    1. init nvs
    2. read then write the default value if empty nvs
    3. enable Bluetooth (which inits the nvs again)
    4. connect to a central and enable some characteristics
    5. write a new value to nvs
    6. read the last value from nvs
  • Are these 2 sectors currently placed in the same partition as Bluetooth settings?

    Yes they were...

    But I tried your proposal and it seems working fine.
    The Bluetooth settings now takes 4 sectors instead of 8.

    So your point is that every user NVS data should go in a dedicated partition and the OS NVS data will take place in the original storage partition.

    Thank you

  • Thanks for the update.

    So your point is that every user NVS data should go in a dedicated partition and the OS NVS data will take place in the original storage partition.

    I think creating a new storage partition might be the easiest way to ensure separation between the NVS area used by Settings from the NVS area you are using in your application. But it's not the only solution, you could also use the CONFIG_SETTINGS_NVS_SECTOR_COUNT configuration and prevent Settings from allocating the whole partition to itself.

  • Hi Vidar,
    It used to work fine but now I face problem to compile the same code with MCUBoot enabled...

    This MACRO generates an error

    fs.offset = FLASH_AREA_OFFSET(user_storage);

    If I use one partition named storage this work but as soon as I split it in storage + user-storage it fails.

    The overlay of my custom board nRF52840 is as below

    /* User storage */
    &flash0 {
        partitions {
            storage_partition: partition@f8000 {
                label = "storage";
                reg = < 0xf8000 0x6000 >;
            };
                
            user_partition: partition@fe000 {
                label = "user-storage";
                reg = < 0xfe000 0x2000 >;
            };
        };
    };

    proj.conf extract

    NVS concern:
    
    # Enable bonding
    CONFIG_SETTINGS=y
    CONFIG_BT_BONDABLE=y
    CONFIG_BT_SETTINGS=y
    CONFIG_FLASH=y
    CONFIG_FLASH_PAGE_LAYOUT=y
    CONFIG_FLASH_MAP=y
    CONFIG_NVS=y
    CONFIG_SETTINGS_NVS=y
    CONFIG_SETTINGS_NVS_SECTOR_COUNT=4
    
    New lines MCUBoot concern:
    
    # Bootloader
    CONFIG_BOOTLOADER_MCUBOOT=y
    CONFIG_MCUBOOT_UTIL_LOG_LEVEL_DBG=y
    CONFIG_MCUMGR_LOG_LEVEL_DBG=y
    
    # DFU and OTA update
    CONFIG_DFU_TARGET=y
    CONFIG_DFU_TARGET_MCUBOOT=y
    CONFIG_FLASH=y
    CONFIG_IMG_ERASE_PROGRESSIVELY=y
    CONFIG_IMG_MANAGER=y
    CONFIG_MCUBOOT_IMG_MANAGER=y
    CONFIG_RING_BUFFER=y
    
    # Firmware signing
    CONFIG_SIGN_IMAGES=y

    Any idea on what could be wrong ?

    Best regards.

  • Hi,

    I should have pointed this out earlier, but the partition manager will take over and manage the memory layout once you start doing Multi-image builds. This means that the DTS configuration will be ignored.

    Please try to add the yaml code below into a file named "pm_static.yml" and place it in your project directory. This should configure the partition manager to include your partition.

    user_storage:
      address: 0xfc000
      size: 0x2000
      end_address:0xfe000
      placement:
        before: 
        - settings_storage
      region: flash_primary
    settings_storage:
      address: 0xfe000
      size: 0x2000
      end_address: 0x100000
      placement:
        before:
        - end
      region: flash_primary

    Best regards,

    Vidar

  • Vidar,

    The error still remains.

    This is not clear for me, the dts and overlay files will be ignored about &flash0 part only ?

    The content seems not identical to my overlay file...  Is the code below the "perfect" equivalence of my overlay ? (it doesn't work neither)

    storage:
      address: 0xf8000
      size: 0x6000
      end_address: 0xfe000
      placement:
        before: 
        - user_storage
      region: flash_primary
    user_storage:
      address: 0xfe000
      size: 0x2000
      end_address: 0x100000
      placement:
        before:
        - end
      region: flash_primary

    Edit: I can build now

    According to my pm_static.yml there is 3 "storage" partitions

    - settings_storage size 0x2000 (generated only with MCU Boot)

    - storage size 0x6000 (default 0x8000)

    - user_storage size 0x2000 (new custom partition from storage)

    Knowing this, CONFIG_SETTINGS_NVS_SECTOR_COUNT=4 should still influence on storage ?

    ...
    settings_storage:
      address: 0xf6000
      end_address: 0xf8000
      placement:
        before:
        - end
      region: flash_primary
      size: 0x2000
    sram_primary:
      address: 0x20000000
      end_address: 0x20040000
      region: sram_primary
      size: 0x40000
    storage:
      address: 0xf8000
      end_address: 0xfe000
      placement:
        before:
        - user_storage
      region: flash_primary
      size: 0x6000
    user_storage:
      address: 0xfe000
      end_address: 0x100000
      placement:
        before:
        - end
      region: flash_primary
      size: 0x2000

Reply
  • Vidar,

    The error still remains.

    This is not clear for me, the dts and overlay files will be ignored about &flash0 part only ?

    The content seems not identical to my overlay file...  Is the code below the "perfect" equivalence of my overlay ? (it doesn't work neither)

    storage:
      address: 0xf8000
      size: 0x6000
      end_address: 0xfe000
      placement:
        before: 
        - user_storage
      region: flash_primary
    user_storage:
      address: 0xfe000
      size: 0x2000
      end_address: 0x100000
      placement:
        before:
        - end
      region: flash_primary

    Edit: I can build now

    According to my pm_static.yml there is 3 "storage" partitions

    - settings_storage size 0x2000 (generated only with MCU Boot)

    - storage size 0x6000 (default 0x8000)

    - user_storage size 0x2000 (new custom partition from storage)

    Knowing this, CONFIG_SETTINGS_NVS_SECTOR_COUNT=4 should still influence on storage ?

    ...
    settings_storage:
      address: 0xf6000
      end_address: 0xf8000
      placement:
        before:
        - end
      region: flash_primary
      size: 0x2000
    sram_primary:
      address: 0x20000000
      end_address: 0x20040000
      region: sram_primary
      size: 0x40000
    storage:
      address: 0xf8000
      end_address: 0xfe000
      placement:
        before:
        - user_storage
      region: flash_primary
      size: 0x6000
    user_storage:
      address: 0xfe000
      end_address: 0x100000
      placement:
        before:
        - end
      region: flash_primary
      size: 0x2000

Children
  • The settings module will use the 'settings_storage' instead of the 'storage' partition now when the Partition Manager is enabled, so you can remove the storage partition and keep settings_storage + user_storage.

    CONFIG_SETTINGS_NVS_SECTOR_COUNT will work in the same way as before.

Related