ESP32 Non Volatile Storage tutorial

 NVS stands for Non-volatile Storage 


This library is designed to store key-value pairs to flash 


By default The flash has an NVS partition at 0x9000 offset address, it contains the wifi data 



We will go through this example to make use of the NVS memory 

https://github.com/espressif/esp-idf/tree/master/examples/storage/nvs_rw_value


At first NVS partition is initialized, if there are no free pages then it is erased and re-initialized again 

    // Initialize NVS
    esp_err_t err = nvs_flash_init();
    if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        // NVS partition was truncated and needs to be erased
        // Retry nvs_flash_init
        ESP_ERROR_CHECK(nvs_flash_erase());
        err = nvs_flash_init();
    }
    ESP_ERROR_CHECK( err );



Multiple internal ESP-IDF and 3rd Party apps can store key-value pairs in the NVS partition using this library. in order to reduce possible conflicts on key names, the library provides a way for the user to store values by creating Namespace first. 


* @param[in]   name        Namespace name.
* @param[in]   open_mode   NVS_READWRITE or NVS_READONLY.
* @param[out]  out_handle  If successful (return code is zero), handle will be returned

esp_err_t nvs_open(
                  const char* name,
                  nvs_open_mode_t open_mode,
                  nvs_handle_t *out_handle

                  );


At first, create a handle to reference the further usage of NVS 


nvs_handle_t my_handle;

 

Then open the namespace 

err = nvs_open("storage", NVS_READWRITE, &my_handle);


To set/ save a value for a key use the following function 

* @param[in]  handle  Handle obtained from nvs_open function.
* @param[in]  key     Key name.
* @param[in]  value   The value to set.
*                     For strings, the maximum length (including null character) is
*                     4000 bytes.

esp_err_t nvs_set_i32 (

                      nvs_handle_t handle, 

                      const char* key, 

                      int32_t value

                      );


After writing a value you must commit to ensuring changes are written to flash storage 

esp_err_t nvs_commit(nvs_handle_t handle);


To read from the key use the following function

* @param[in]     handle     Handle obtained from nvs_open function.
* @param[in]     key        Key name.
* @param          out_value  Pointer to the output value.

esp_err_t nvs_get_i32 (nvs_handle_t handle, const char* key, int32_t* out_value);

After usage close the handle 

/**
* @brief      Close the storage handle and free any allocated resources
*
* This function should be called for each handle opened with nvs_open once
* the handle is not in use any more
*
* @param[in]  handle  Storage handle to close
*/

void nvs_close(nvs_handle_t handle);

Build and run the example on the ESP32 


The output of the program : 



Please take a look at the following snippet from Espressif. It has some important info on the partition 



Wrapping the NVS in, we can easily create a custom database library. I have designed a lot of databases on top of NVS. There are some design patterns that work by creating a cache in RAM thereby preventing excessive write cycles to NVS. this is also known as wear-leveling 


0 comments:

Post a Comment

Categories

Pages

Firmware Engineer

My photo
Works on Firmware, Embedded Linux, Smart Metering, RTOS, IoT backend

Contact Form

Name

Email *

Message *

Copyrighted by Hassin. Powered by Blogger.