writing to NVS
Re: writing to NVS
For about 1K of data in total, written/re-written once a day and everything else being equal, I'd suggest using NVS and call it good.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32
Re: writing to NVS
I use NVS for stuff like this including several 128 bit UUIDs.mzimmers wrote: I'm not sure what the author meant by "many," but I'm going to need to store maybe 10 elements, none of which are big. They'll be things like:
- MAC Address
serial number
device name
number of writes to NVS
John A
Re: writing to NVS
OK then, NVS it is. Now the next question: where to put it.
I'm looking at the address mapping table in the reference manual, and if I'm reading it right, valid data addresses are 0x3ff8 0000 through 0x3fff ffff. Some of this space is reserved for system functions, but it appears that 0x3ff9 0000 through 0x3ff9 ffff is available.
My partitions file has the following entries for data partitions:
nvs,data,nvs,0x9000,16K,
otadata,data,ota,0xd000,8K,
phy_init,data,phy,0xf000,4K,
The addresses in this table are offsets, but I don't know from what.
So...how do I go about finding a free area for my application data?
I'm looking at the address mapping table in the reference manual, and if I'm reading it right, valid data addresses are 0x3ff8 0000 through 0x3fff ffff. Some of this space is reserved for system functions, but it appears that 0x3ff9 0000 through 0x3ff9 ffff is available.
My partitions file has the following entries for data partitions:
nvs,data,nvs,0x9000,16K,
otadata,data,ota,0xd000,8K,
phy_init,data,phy,0xf000,4K,
The addresses in this table are offsets, but I don't know from what.
So...how do I go about finding a free area for my application data?
Re: writing to NVS
Could you be missing the point of NVS?
The idea behind NVS in ESP-IDF is to hide from you the complexities of reading and writing flash storage. The model of NVS is that you can create name/value pairs and NVS takes care of saving them for you and retrieving them when you request. When working with NVS, you should never have to "see" a memory address. The way I understand NVS to work is that you create a partition in flash and call that partition "nvs". It doesn't matter where in flash it is. You then access NVS through the high level NVS APIs. Again, no memory addresses involved.
The idea behind NVS in ESP-IDF is to hide from you the complexities of reading and writing flash storage. The model of NVS is that you can create name/value pairs and NVS takes care of saving them for you and retrieving them when you request. When working with NVS, you should never have to "see" a memory address. The way I understand NVS to work is that you create a partition in flash and call that partition "nvs". It doesn't matter where in flash it is. You then access NVS through the high level NVS APIs. Again, no memory addresses involved.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32
Re: writing to NVS
Ohhhhhh, I see now...the NVS facility uses the nvs partition (duh) that already exists, so I don't need to create my own partition for this.
I just create a namespace and a key for my blob, and use them when making nvs_open/nvs_get_blob/nvs_set_blob/nvs_commit/nvs_close calls.
That about right?
I just create a namespace and a key for my blob, and use them when making nvs_open/nvs_get_blob/nvs_set_blob/nvs_commit/nvs_close calls.
That about right?
Re: writing to NVS
That's my understanding. The NVS subsystem un-burdens you from the low-level gorp and all you have to think about is what you want to store and retrieve and how to name it ... and NVS takes care of the mechanics of actually doing the work of storing and retrieving it for you behind the scenes.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32
Re: writing to NVS
Yeah, that makes more sense now. I don't have it working quite right yet, though. Here's a code snippet:
The nvs_get_blob() call returns 0x1102, which is:
https://github.com/espressif/esp-idf/bl ... ple_main.c except with a blob instead of an int.
Code: Select all
void Nvs::read(NvStruct *nvp)
#define STORAGE_NAMESPACE "my_namespace"
#define STORAGE_KEY "my_storage_key"
{
esp_err_t err = ESP_OK;
err = nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &handle);
assert (err == ESP_OK);
err = nvs_get_blob(handle, STORAGE_KEY, nvp, &structSize);
Any idea what I'm doing wrong here? I'm trying to mimic the code here:#define ESP_ERR_NVS_NOT_FOUND (ESP_ERR_NVS_BASE + 0x02) /*!< Id namespace doesn’t exist yet and mode is NVS_READONLY */
https://github.com/espressif/esp-idf/bl ... ple_main.c except with a blob instead of an int.
Re: writing to NVS
By calling nvs_get_blob(name) you are asking for the previously saved data that was previously saved with a call nvs_set_blob(name, value). I would expect such an error if you had not previously successfully saved a blob with that name.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32
Re: writing to NVS
That makes perfect sense, but I don't see anything else in the example I tried to follow (or on the follow the docs page). So, how does one execute the initial read or write to a new namespace?
EDIT: I think I found the problem: the correct sequence for the first time one uses a given key is:
- nvs_open()
- nvs_set_blob()
- nvs_commit()
- nvs_close()
- nvs_open()
- nvs_get_blob()
A couple of notes for posterity:
1. your get/set functions must "agree"; that is, you can't nvs_get_i8() on the same key that you used for, say, nvs_set_u8(). It will give you an 1102 error, which is probably pedagogically correct, but somewhat misleading. This makes sense in retrospect, as things are stored as typed key/value pairs, but it caused me a little trouble during debugging.
2. The docs, in a couple places, say this:
Anyway, I think I've got this now. Thanks for all the assistance.
EDIT: I think I found the problem: the correct sequence for the first time one uses a given key is:
- nvs_open()
- nvs_set_blob()
- nvs_commit()
- nvs_close()
- nvs_open()
- nvs_get_blob()
A couple of notes for posterity:
1. your get/set functions must "agree"; that is, you can't nvs_get_i8() on the same key that you used for, say, nvs_set_u8(). It will give you an 1102 error, which is probably pedagogically correct, but somewhat misleading. This makes sense in retrospect, as things are stored as typed key/value pairs, but it caused me a little trouble during debugging.
2. The docs, in a couple places, say this:
This probably should be re-written. It's confusing, in that the wording suggests that its value is returned by the function, and I think it's also incorrect, in that the key is at *most* 15 characters (anything longer will return ESP_ERR_NVS_KEY_TOO_LONG).key: Key name. Maximal length is determined by the underlying implementation, but is guaranteed to be at least 15 characters. Shouldn’t be empty.
Anyway, I think I've got this now. Thanks for all the assistance.
Re: writing to NVS
The documentation I'm looking at says this...
https://esp-idf.readthedocs.io/en/lates ... flash.htmlNVS operates on key-value pairs. Keys are ASCII strings, maximum key length is currently 15 characters.
Who is online
Users browsing this forum: No registered users and 138 guests