NVS behavior with frequent data storage

Hi,

I am using the NVS to store my application data in the defined partition starting from a flash address of 0xFC000 to 0x100000. 

I have 3 structures with variable sizes. Here structure 1 and structure 2 will be stored at keys 1 and 2 respectively whereas structure 3 will store at key 3. As per the NVS architecture, the updated data will be append after the last write in Flash.

The application of Structure 3 is such that it requires frequent writing in the flash, so key 3 will always store the new data at the next address of the last data. Once the NVS reaches the end of the last address (in my case it is 0x100000),  it starts the Garbage collection to free up the spaces for the next storage.

Here structure 1 and structure 2 at key 1 and 2 respectively still at their previous location as it was not updated in between. 

So my question is, how the NVS will manage the garbage collection where it allows new space for Structure 3 while keeping Structure 1 and Structure 2 to manage their value?

Hardware: nRF52840
NCS: 2.6.2

Parents
  • Hi,

    Maybe it is easiest to make two separate NVS partitions: One for 1+2 and one for 3?

    I must admit I have not had the use-case you talk of myself before, but looking at NVS APIs, I cannot see anything that seems to "preserve" a NVS struct.

    Regards,
    Sigurd Hellesvik

  • Hi,

    Thanks for you reply.

    As far as I saw the NVS usage initialization, requires a partition while initializing the NVS. Consider the code sample for example 

    #define NVS_PARTITION		            data_storage_partition
    #define NVS_PARTITION_DEVICE	        FIXED_PARTITION_DEVICE(NVS_PARTITION)
    #define NVS_PARTITION_OFFSET	        FIXED_PARTITION_OFFSET(NVS_PARTITION)
    
    
    /* Global structure to handle NVS file system operations */
    struct nvs_fs g_fs; 
    
    // Setting device 
    g_fs.flash_device = NVS_PARTITION_DEVICE;
    if (!device_is_ready(g_fs.flash_device)) {
    	LOG_ERR("Flash device %s is not ready\n", g_fs.flash_device->name);
        return -ENODEV;
    }
    LOG_DBG("NVS flash is ready");
    
    // setting partition
    g_fs.offset = NVS_PARTITION_OFFSET;
    ret = flash_get_page_info_by_offs(g_fs.flash_device, g_fs.offset, &info);
    if (ret) {
        LOG_ERR("Failed to get page info with Error :: %d", ret);
    	return ret;
    }
    
    g_fs.sector_size = info.size;
    g_fs.sector_count = NVS_FS_SECTOR_CNT;
    
    // Mount the NVS file system
    ret = nvs_mount(&g_fs);
    if (ret) {
    	LOG_ERR("Failed to mount file system with Error :: %d", ret);
    }
    

    Here data_storage_partition is the partition to store the application data. As per your suggestion if I create another partition named data_storage_three_partition that only stores structure 3 data, then how NVS will decide which partition the NVS will use to store structure 3 data to data_storage_three_partition and Structure 1, and 2 data to data_storage_partition.

    Also, how can we modify the above code to use a separate partition for the same NVS?

    Regards,

    Ankit

  • You can make another "struct nvs_fs" to keep track of the structure 3 data, and initialize and write to that in the same way. Then you need application logic to differentiate which NVS object you use for which data.

    Did this explanation make sense?

  • I see. So I need to have two struct nvs_fs like nvs_fs_1, nvs_fs_2 where nvs_fs_1 will be used to store key 1 and 2 data and nvs_fs_2 will be used to store the key 3 data.

    I need to use either nvs_fs _1 or nvs_fs_2 based on the key in the application.

  • This is my suggested solution yes.

    Will that work for your application?

Reply Children
No Data
Related