Como ler valor do NVS do ESP32 em std::string

Em nosso post anterior, discutimos Como obter o comprimento / tamanho de um valor NVS no ESP32. Baseado nisso, podemos ler um valor NVS em uma std::string.

Estratégia

  1. Determinar o tamanho do valor no NVS
  2. Alocar buffer temporário do tamanho determinado
  3. Ler valor do NVS para o buffer temporário
  4. Criar std::string do valor
  5. Limpar buffer temporário

Função utilitária para ler valor NVS como std::string

Caso a chave não exista no NVS, esta função retornará a string vazia ("").

read_nvs_to_stdstring.cpp
#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;
}

Exemplo de uso

Isso assume que você configurou myNvs como mostramos em nosso post anterior Como inicializar NVS no ESP32

example_usage.cpp
std::string value = ReadNVSValueAsStdString(myNvs, "MyKey");

Otimizações C++17

A partir do C++17, você possivelmente pode criar uma std::string diretamente em vez de usar o buffer temporário, já que há uma sobrecarga de .data() que retorna um ponteiro não-const - então você pode escrever diretamente no buffer da std::string.

No entanto, como minha toolchain baseada em PlatformIO atualmente não suporta isso, eu não escrevi esse código ainda.


Check out similar posts by category: C/C++, ESP8266/ESP32