Page 1 of 1

NVS commit / rollback

Posted: Mon Sep 21, 2020 7:05 am
by fschuetz
Dear all

I could not find any information on this so I ask the question here. If this is already answered somewhere else, please refer me to this information.

I do store various uint32_t and one character array that are all members of the same struct as individual values in nvs. I store those individually rather than the full structure as a blob as the manual (https://docs.espressif.com/projects/esp ... flash.html) states "NVS works best for storing many small values, rather than a few large values of the type ‘string’ and ‘blob’".

I want to ensure that either all values are written or none. The function description of nvs_set_* states "Note that actual storage will not be updated until nvs_commit function is called." while the description for nvs_commit states "After setting any values, nvs_commit() must be called to ensure changes are written to non-volatile storage. Individual implementations may write to storage at other times, but this is not guaranteed."

I am unsure on how to interpret this: Does this mean, that unless I call nvs_commit in my function, the values are NEVER commited to nvs, even if another function in a concurrent process calls nvs commit in the same namespace (using its own handle)? Or does this mean that the commit could happen nevertheless and I need to first read all the old values to memory, update the values using the nvs_set function and if all updates are successful, commit, otherwise try to write back the old values from ram?

Thanks for helping

Florian

Re: NVS commit / rollback

Posted: Tue Sep 22, 2020 8:52 am
by ESP_Sprite
If you want atomic updates, you'll need to write the entire struct. NVS doesn't have a thing like transactions, sorry.

Re: NVS commit / rollback

Posted: Tue Sep 22, 2020 5:43 pm
by fschuetz
Thanks for the answer. Got that. Two more questions that relate to the topic:

1. What is the downside of writing a struct as a blob rather than store its individual (uint16_t) fields? (ie why does the manual state writing ints is preferred to blobs)?

2. Is there any chance, that values are committed even if I don't call commit - possible due to another commit with another handle in another thread to the same namespace? (the manual leaves the likelihood open)

Thanks for your answer.

Best,
Florian

Re: NVS commit / rollback

Posted: Wed Sep 23, 2020 11:00 am
by ESP_Sprite
The downside of a blob is that the entire blob needs to be rewritten even when you only change one member. Depending on the size of the blob, this means slower writing plus more erase cycles (=wear on the flash). Depending on your program and how often you rewrite the data, this may or may not matter in your use case.

From how I read it, committing gives the guarantee that the data is actually written to cache. A NVS write may or may not be cached in internal memory before it's written, and the implementation may decide to do the write to flash at any time, but it *has* to do it when the commit function is called. In other words: if the data makes it to NVS before committing is implementation-defined and you should not rely on any specific behaviour there.

Re: NVS commit / rollback

Posted: Wed Sep 23, 2020 7:23 pm
by fschuetz
Thank you for the explanation. This confirms my assumption. I will just use a blob as it rarely needs to be written (once every couple of weeks) and when a write is needed most values of the struct have changed anyways. Wear should not be a problem.