ESP8266/ESP32 NVS 數據存儲基本操作

轉載:espressif

NVS 介紹

NVS: Non-volatile storage , 即將數據存儲到 flash 中, 掉電或重啓後數據仍然存在, flash 類似於 PC 上磁盤.
ESP8266 和 ESP32 上提供 nvs 接口給用戶, 來保存和讀取用戶數據. 具體參考 nvs.h
nvs 更詳細的說明請參考: NVS 文檔

NVS 優勢

  • 接口更加安全

    相比較於 spi_flash_readspi_flash_write 等接口, NVS 不直接操作 address. 對於終端用戶而已, 更加安全.
    例如: 應用複雜一點, 容易 spi_flash_write(address, src, size) 不小心寫到同一個地址, 或地址寫覆蓋, 而導致長時間 debug

  • 接口使用接近用戶習慣

    NVS 接口類似於電腦上操作文件一樣:
    打開文件(nvs_open), 寫文件(nvs_set_xxx), 保存文件(nvs_commit), 關閉文件(nvs_close)
    打開文件(nvs_open), 讀取文件(nvs_get_xxx), 關閉文件(nvs_close)

  • 擦寫均衡, 使 flash 壽命更長

    NVS 在操作少量數據上, NVS 分區更大時, 擦寫均衡表現的更爲明顯.

    例如: flash 一個 sector4KB, NVS 分配大小爲一個 sector, 寫同一個 64 Bytes 數據到 flash, 分別比較 spi_flash_xxxnvs 寫 64 次

  • spi_flash_write: 每次寫 flash 前, 需擦除 flash. 對應: 64 次擦除 flash, 64 次寫 flash

  • nvs: nvs 內部有擦寫均衡, 有標誌位記錄當前有效存儲. 如第一次擦除 sector, 再寫 sector 0-63 Byte, 第二次寫 sector 64-127 Bytes, 第 64 次(4KB/64Bytes) 寫完 sector 最後一個 64 Byte. 對應: 1 次擦除 flash, 64 次寫 flash
    這樣 NVS 減少 64 倍擦除操作, 對 flash 壽命有較大提升.
    NVS 分區更大, 存儲信息少時, 表現的更爲明顯.

NVS 寫

void nvs_write_data_to_flash(void)
{
    nvs_handle handle;
    static const char *NVS_CUSTOMER = "customer data";
    static const char *DATA1 = "param 1";
    static const char *DATA2 = "param 2";
    static const char *DATA3 = "param 3";

    int32_t value_for_store = 666;

     wifi_config_t wifi_config_to_store = {
        .sta = {
            .ssid = "store_ssid:hello_kitty",
            .password = "store_password:1234567890",
        },
    };

    printf("set size:%u\r\n", sizeof(wifi_config_to_store));
    ESP_ERROR_CHECK( nvs_open( NVS_CUSTOMER, NVS_READWRITE, &handle) );
    ESP_ERROR_CHECK( nvs_set_str( handle, DATA1, "i am a string.") );
    ESP_ERROR_CHECK( nvs_set_i32( handle, DATA2, value_for_store) );
    ESP_ERROR_CHECK( nvs_set_blob( handle, DATA3, &wifi_config_to_store, sizeof(wifi_config_to_store)) );

    ESP_ERROR_CHECK( nvs_commit(handle) );
    nvs_close(handle);

}

NVS 讀

void nvs_read_data_from_flash(void)
{
    nvs_handle handle;
    static const char *NVS_CUSTOMER = "customer data";
    static const char *DATA1 = "param 1";
    static const char *DATA2 = "param 2";
    static const char *DATA3 = "param 3";

    uint32_t str_length = 32;
    char str_data[32] = {0};
    int32_t value = 0;
    wifi_config_t wifi_config_stored;
    memset(&wifi_config_stored, 0x0, sizeof(wifi_config_stored));
    uint32_t len = sizeof(wifi_config_stored);

    ESP_ERROR_CHECK( nvs_open(NVS_CUSTOMER, NVS_READWRITE, &handle) );

    ESP_ERROR_CHECK ( nvs_get_str(handle, DATA1, str_data, &str_length) );
    ESP_ERROR_CHECK ( nvs_get_i32(handle, DATA2, &value) );
    ESP_ERROR_CHECK ( nvs_get_blob(handle, DATA3, &wifi_config_stored, &len) );

    printf("[data1]: %s len:%u\r\n", str_data, str_length);
    printf("[data2]: %d\r\n", value);
    printf("[data3]: ssid:%s passwd:%s\r\n", wifi_config_stored.sta.ssid, wifi_config_stored.sta.password);

    nvs_close(handle);
}

其他說明

  • 不限於上面功能, nvs.h 中提供更多接口給用戶使用
  • 可參考 esp-idf nvs blob demo來測試相關接口和使用
  • NVS說明文檔
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章