NVS 介绍
NVS: Non-volatile storage , 即将数据存储到 flash 中, 掉电或重启后数据仍然存在, flash 类似于 PC 上磁盘.
ESP8266 和 ESP32 上提供 nvs 接口给用户, 来保存和读取用户数据. 具体参考 nvs.h
nvs 更详细的说明请参考: NVS 文档
NVS 优势
接口更加安全
相比较于 spi_flash_read 和 spi_flash_write 等接口, NVS 不直接操作 address. 对于终端用户而已, 更加安全.
例如: 应用复杂一点, 容易 spi_flash_writeaddress, src, size) 不小心写到同一个地址, 或地址写覆盖, 而导致长时间 debug
接口使用接近用户习惯
NVS 接口类似于电脑上操作文件一样:
打开文件nvs_open), 写文件nvs_set_xxx), 保存文件nvs_commit), 关闭文件nvs_close)
打开文件nvs_open), 读取文件nvs_get_xxx), 关闭文件nvs_close)
擦写均衡, 使 flash 寿命更长
NVS 在操作少量数据上, NVS 分区更大时, 擦写均衡表现的更为明显.
例如: flash 一个 sector 为 4KB, NVS 分配大小为一个 sector, 写同一个 64 Bytes 数据到 flash, 分别比较 spi_flash_xxx 和 nvs 写 64 次
spi_flash_write: 每次写 flash 前, 需擦除 flash. 对应: 64 次擦除 flash, 64 次写 flashnvs: 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 写
更多参考: nvs.h
void nvs_write_data_to_flashvoid){ 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”, sizeofwifi_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, sizeofwifi_config_to_store)) ); ESP_ERROR_CHECK nvs_commithandle) ); nvs_closehandle);} NVS 读
更多参考: nvs.h
void nvs_read_data_from_flashvoid){ 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, sizeofwifi_config_stored)); uint32_t len = sizeofwifi_config_stored); ESP_ERROR_CHECK nvs_openNVS_CUSTOMER, NVS_READWRITE, &handle) ); ESP_ERROR_CHECK nvs_get_strhandle, DATA1, str_data, &str_length) ); ESP_ERROR_CHECK nvs_get_i32handle, DATA2, &value) ); ESP_ERROR_CHECK nvs_get_blobhandle, 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_closehandle);} 其他说明 不限于上面功能, nvs.h 中提供更多接口给用户使用可参考 esp-idf nvs blob demo 来测试相关接口和使用NVS 说明文档