SOLVED: NVS data set or erase FAILS; NVS becomes read-only
Posted: Sun Jun 12, 2022 9:42 pm
We use the "Non Volatile Storage" library to store user registrations and other application settings in our ESP32 project (See https://docs.espressif.com/projects/esp ... flash.html).
We have run into an intermittent problem where nvs_set_* functions start to fail: They do not return any error code, but the new value has NOT been added to the NVS. This effects updating an existing key (value doesn't change) and adding a new key (key not added; dump of all keys shows only keys which already existed).
Here is my "set" code to store a value:
Once the problem has occurred, no further writes using the NVS library work, although reading values is OK. The problem persists after a power cycle.
I have a "factory reset" triggered by a button press, but this does not fix the problem. Here is the "factory reset" code and log output, which demonstrate the issue:
"DebugPrintKeys" is a debug function which iterates through all keys in our nvs name space and prints the key names to the log. It should print "No keys found" after a nvs_flash_erase, which it does when things are working correctly.
After the error has occurred, the log shows the following for a factory reset:
I.e. All the previously stored keys are still there (not erased). After rebooting, attempts to read the nvs keys confirm that they are still there, and the bug persists (adding / updating values fails).
The only way I've found to restore the correct operation of the NVS is to perform a full flash erase using the boot loader mode, i.e.:
esptool.py -p com4 erase_flash
Then reinstall the firmware. This does work.
I've tried uploading and analysing the content of the NVS partition from a device with the bug, in case it was corrupt. The content looks OK (based on the documentation for the NVS library) and I can see the stored namespaces, keys and data. Note that a "factory reset" as above had been performed, so all the entries SHOULD have been erased, but they appeared to be still intact.
Also, I was able to download the nvs partition data from the failed board to another board using "write_flash..." command. This worked OK - the original keys and values from the failed board were there, and I was able to update and erase as normal.
Any suggestions? I'm pretty stuck because I can't replicate the bug; it's intermittent, i.e. only happens when the device is given to the testers! However it has now happened 3 or 4 times and renders the device useless until a flash erase is done.
ESP-IDF 4.3; ESP32-WROOM module, chip revision: 3.
We have run into an intermittent problem where nvs_set_* functions start to fail: They do not return any error code, but the new value has NOT been added to the NVS. This effects updating an existing key (value doesn't change) and adding a new key (key not added; dump of all keys shows only keys which already existed).
Here is my "set" code to store a value:
Code: Select all
// Initialisation:
static const char *NVS_NAMESPACE = "wc_nvs";
esp_err_t result = nvs_flash_init();
if (result == ESP_ERR_NVS_NO_FREE_PAGES || result == ESP_ERR_NVS_NEW_VERSION_FOUND)
{
ESP_ERROR_CHECK( nvs_flash_erase() );
result = nvs_flash_init();
}
ESP_ERROR_CHECK( result );
ESP_ERROR_CHECK( nvs_open(NVS_NAMESPACE, NVS_READWRITE, &l_nvs_handle) );
...
// Write a key / value:
ESP_ERROR_CHECK( nvs_set_blob(l_nvs_handle, key, data, size) );
ESP_ERROR_CHECK( nvs_commit(l_nvs_handle) );
I have a "factory reset" triggered by a button press, but this does not fix the problem. Here is the "factory reset" code and log output, which demonstrate the issue:
Code: Select all
static void OnStandbyButtonHold(void)
{
ESP_LOGI(TAG, "************* FACTORY RESET *************");
WcNvsEraseFlash();
WC_EXIT_ALWAYS();
}
...
void WcNvsEraseFlash(void)
{
nvs_close(l_nvs_handle);
ESP_LOGI(TAG, "ERASE NVS partition...");
ESP_ERROR_CHECK( nvs_flash_erase() );
ESP_LOGI(TAG, "NVS Erase finished.");
// After an erase, the flash is de-initialised. Need to initialise and re-open:
ESP_ERROR_CHECK( nvs_flash_init() );
ESP_ERROR_CHECK( nvs_open(NVS_NAMESPACE, NVS_READWRITE, &l_nvs_handle) );
// ***** Debug flash erase issue: print flash contents - should be empty! **********
DebugPrintKeys();
}
After the error has occurred, the log shows the following for a factory reset:
Code: Select all
I (2360495) WCUI: ************* FACTORY RESET *************
I (2360495) NVSC: ERASE NVS partition...
I (2360495) NVSC: NVS Erase finished.
I (2360525) NVSC: NVS Keys:
I (2360525) NVSC: Key: 'name_zone_1'; type 66
I (2360525) NVSC: Key: 'name_zone_2'; type 66
I (2360535) NVSC: Key: 'name_zone_3'; type 66
I (2360535) NVSC: Key: 'name_zone_4'; type 66
I (2360545) NVSC: Key: 'name_zone_5'; type 66
I (2360545) NVSC: Key: 'name_zone_6'; type 66
I (2360555) NVSC: Key: 'serial_engr'; type 33
I (2360565) NVSC: Key: '01_reg_data'; type 66
I (2360565) NVSC: Key: '02_reg_data'; type 66
I (2360575) NVSC: Key: 'use_stand_ble'; type 4
I (2360575) NVSC: Key: 'use_target_ble'; type 4
I (2360585) NVSC: Key: 'name_engr'; type 66
I (2360585) NVSC: NVS Stats: used entries 104; free entries 904; all entries 1008
The only way I've found to restore the correct operation of the NVS is to perform a full flash erase using the boot loader mode, i.e.:
esptool.py -p com4 erase_flash
Then reinstall the firmware. This does work.
I've tried uploading and analysing the content of the NVS partition from a device with the bug, in case it was corrupt. The content looks OK (based on the documentation for the NVS library) and I can see the stored namespaces, keys and data. Note that a "factory reset" as above had been performed, so all the entries SHOULD have been erased, but they appeared to be still intact.
Also, I was able to download the nvs partition data from the failed board to another board using "write_flash..." command. This worked OK - the original keys and values from the failed board were there, and I was able to update and erase as normal.
Any suggestions? I'm pretty stuck because I can't replicate the bug; it's intermittent, i.e. only happens when the device is given to the testers! However it has now happened 3 or 4 times and renders the device useless until a flash erase is done.
ESP-IDF 4.3; ESP32-WROOM module, chip revision: 3.