In our previous post, we discussed How to get the length / size of NVS value on ESP32. Based on that, we can read a NVS value into a std::string
.
Strategy
- Determine size of value in NVS
- Allocate temporary buffer of the determined size
- Read value from NVS into temporary buffer
- Create
std::string
from value - Cleanup temporary buffer
Utility function to read NVS value as std::string
In case the key does not exist in NVS, this function will return the empty string (""
).
#include <nvs.h> #include <string> std::string ReadNVSValueAsStdString(nvs_handle_t nvs, const char* key) { /** * Strategy: * 1. Determine size of value in NVS * 2. Allocate temporary buffer of determined size * 3. Read value from NVS into temporary buffer * 4. Create std::string from value * 5. Cleanup */ // Step 1: Get size of key esp_err_t err; size_t value_size = 0; if((err = nvs_get_str(nvs, _key.c_str(), nullptr, &value_size)) != ESP_OK) { if(err == ESP_ERR_NVS_NOT_FOUND) { // Not found, no error return ""; } else { printf("Failed to get size of NVS key %s: %s\r\n", key, esp_err_to_name(err)); return; } } // Step 2: Allocate temporary buffer to read from char* buf = (char*)malloc(value_size); // Step 3: Read value into temporary buffer. esp_err_t err; if((err = nvs_get_str(nvs, _key.c_str(), buf, &value_size)) != ESP_OK) { // "Doesn't exist" has already been handled before, so this is an actual error. // We assume that the value did not change between reading the size (step 1) and now. // In case that assumption is value, this will fail with ESP_ERR_NVS_INVALID_LENGTH. // This is extremely unlikely in all usage scenarios, however. printf("Failed to read NVS key %s: %s\r\n", key, esp_err_to_name(err)); free(buf); return ""; } // Step 4: Make string std::string value = std::string(buf, value_size); // Step 5: cleanup free(buf); return value; }
Usage example
This assumes that you have setup myNvs
as we have shown in our previous post How to initialize NVS on ESP32
std::string value = ReadNVSValueAsStdString(myNvs, "MyKey");
C++17 optimizations
Starting from C++17, you can possibly create a std::string
directly instead of using the temporary buffer, since there is an overload of .data()
that returns a non-const
pointer – so you can write directly to the std::string
‘s buffer.
However, since my PlatformIO-based toolchain currently doesn’t support that, I have not written that code yet.