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.