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

Non-volatile storage best practices (Zephyr / NCS)

I have modified the NVS sample in the Zephyr documentation to store some user data on the nrf52832 device. I'm wondering what the best practices are for ensuring the longevity and accuracy of various user-configured parameters. 

My current configuration is as follows:

I have on `user_config_data_t` struct with a number of different parameters shown below:

typedef struct {
    uint32_t user_config_num_writes;
    uint32_t reset_count;

    uint16_t max_cal;
    uint16_t min_cal;

    uint32_t firmware_version;
    uint32_t battery_mv;
    uint8_t battery_percent;

    uint16_t bottle_size;
    uint32_t glow_color;

    bool progress_glow_enabled;

    uint16_t local_bottle_goal;
    
} user_config_data_t;

I am using the given example `nvs_write` function in order to update all of these parameters once per hour if there is a change in any one of them. Shown here:


	if(current_time_in_seconds > (last_nvs_update + (60 * 60))){
		last_nvs_update = current_time_in_seconds;
		user_config_data_t data = read_user_data();
		fresh_data = false;
		if(data.battery_mv != batt_mV){
			data.battery_mv = batt_mV;
			fresh_data = true;
		}
		if(data.battery_percent != batt_percent){
			data.battery_percent = batt_percent;
			fresh_data = true;
		}
		if(data.bottle_size != get_bottle_size()){
			data.bottle_size = get_bottle_size();
			fresh_data = true;
		}
		if(data.firmware_version != FIRMWARE_REVISION){
			fresh_data = true;
		}
		if(data.max_cal != get_hi_cal_point()){
			data.max_cal = get_hi_cal_point();
			fresh_data = true;
		}
		if(data.min_cal != get_low_cal_point()){
			data.min_cal = get_low_cal_point();
			fresh_data = true;
		}
		if(data.local_bottle_goal != get_local_bottle_goal()){
			data.local_bottle_goal = get_local_bottle_goal();
			fresh_data = true;
		}
		if(data.glow_color != get_glow_color()){
			data.glow_color = get_glow_color();
			fresh_data = true;
		}
		if(fresh_data){
			write_user_data(data);
		}
	}

I am a little worried about the durability of this implementation. Are there any suggestions of how to ensure my user data will not be corrupted? Should I be incrementing the data address at some certain interval? Does the nvs library handle all of these nuances for me? 

  • Here is the `read_user_data` function definition for the call made on line 3 of the second code block.  

    user_config_data_t read_user_data(void){
        nvs_read(&fs, USER_DATA_ADDRESS, &user_config_data, sizeof(user_config_data));
        return user_config_data;
    }

  • What is the sector size and sector count you're using?

    Check out the section NVS→Flash Wear, which shows you how you can calculate the expected life time of the device.

    Your numbers should be the following:

    • Sector size nrf52832 (SECTOR_SIZE): ? bytes
    • Sector count (SECTOR_COUNT): ?
    • Page erases: (PAGE_ERASES): 10.000 erase/write cycles for the nRF52832
    • Data size (DS): 30 bytes
      • Size of user_config_data_t
    • Storage request per minute (NS): 1/60 = 0,01667 req/minute

    Fill in the sector size and sector count and calculate the expected life time:

    • SECTOR_COUNT * SECTOR_SIZE * 10000 / (0,01667 * (30+8)) minutes

    Best regards,

    Simon

Related