Closed petermagdy94 closed 3 years ago
@petermagdy94 This is normal — NVS appends new key-value pairs instead of immediately overwriting the existing ones as a flash wear levelling measure. This allows erasing one 4kB flash sector only when it fills up, and not for each value update. NVS keeps track of the state of the key-value pair (not written yet / written and valid / invalidated) using a bitmap at the beginning of the flash sector. Appending the new entry and marking the previous entry as invalid can be done without doing a sector erase.
There is a description of how NVS works here, please take a look: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/nvs_flash.html#internals.
Ok, but is it good for production ? because i also noticed in my project which is using other libraries that also write in nvs partition, each time i write and read the partition, keys are moved to other places and removed from its previous one.
What libraries do you mean by "other libraries that also write in nvs partition"?
There is a situation when it might look like the key-value pair is moved. If the page is full, and new key-value pair can not be appended to the same page, then the value will be written to a new page. Afterwards, the key-value pairs in the old page may get garbage-collected, and the old page will be erased. As a result, you will only see the key being present in the new page.
The approach is suitable for production use. In fact, the log-based approach is also used to ensure that NVS partition can always be recovered if the device is powered off while an operation is in progress, and no key-value pairs will be lost. Keep in mind that for production use we recommend enabling the hardware security features: flash encryption and secure boot. Starting from IDF 4.3, NVS encryption will be enabled automatically if flash encryption is enabled.
If you are worried about access times and fragmentation then you may want to consider using multiple nvs partitions or some kind of ram cache
@igrr actually my project works on arduino platform but i found that the problem is from the lower layer of idf platform, so i mentioned the issue here. the library that writes in nvs is wifimanager [https://github.com/tzapu/WiFiManager.git] or the WiFi library itself. BTW from the documentation and your help, i think there is no chance to corrupt a key-value pair in run time after a bin file is flashed to nvs partition by the factory for production.
@negativekelvin yes you are right, that's another solution but i wanted to make sure that one nvs partition will not make a problem.
If you have some NVS data flashed in factory, I would recommend using two NVS partitions:
nvs
partition, used in read/write modenvs_factory
partition, flashed in factory, and used read-onlyThis will guarantee that no matter what happens with the main NVS partition, the factory settings will not be modified. This setup also works well with the factory reset feature, if you are using it.
For an example of how to use multiple NVS partitions, please check the related section in esp-jumpstart: https://docs.espressif.com/projects/esp-jumpstart/en/latest/manufacturing.html#multiple-nvs-partitions.
thank you all for your help, i used second nvs partition and it works well.
Environment
Problem Description
I ran the example nvs_rw_value, and it's working well and values are read and write as expected. BUT the problem is how this value is saved in memory.
I noticed that when calling nvs_set_i32() or nvs_commit() -i'm not sure which one makes the problem-, the same key is stored in a new place in the memory keeping the previous one. And so after some time the nvs partition is filled with multiple values for this key and overflow the partition again.
Expected Behavior
one key with updated value in the NVS flash.
Actual Behavior
multiple keys of the same key with different values in the NVS flash.
Steps to reproduce
. (path_to_your_idf_directory)/export.sh
idf.py build
idf.py -p COM3 erase_flash
idf.py -p COM3 flash
idf.py -p COM3 monitor
esptool.py -p COM3 read_flash 0x9000 0x5000 ./dump.bin
xxd ./dump.bin
Code to reproduce this issue
Debug Logs
Other items if possible
part of the nvs partition dump read
build_and_dump_files.zip