NVS 优势
接口更加安全
相比较于 spi_flash_read 和 spi_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 一个 sector 为 4KB, NVS 分配大小为一个 sector, 写同一个 64 Bytes 数据到 flash, 分别比较 spi_flash_xxx 和 nvs 写 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 分区更大, 存储信息少时, 表现的更为明显.
项目下载地址:
https://download.csdn.net/download/qq_31806069/11829134
代码段
1、 初始化
void my_nvs_flash_init(void)
{
esp_err_t err;
err = nvs_flash_init();
printf("nvs_flash_init result:%d", err);
ESP_ERROR_CHECK( err );
}
2、 保存uin32_t 类型数据
uint32_t my_nvs_flash_i32_test(void)
{
uint32_t temp;
nvs_handle handle;
printf("i32 test---------->\n");
if ( ESP_OK != nvs_open(NVS_CUSTOMER, NVS_READWRITE, &handle) )
{
printf("nvs open i32 error \n");
}
if (ESP_OK != nvs_get_i32(handle,DATA1_i32,(int32_t*)&temp))
{
printf("nvs get i32 error \n");
}
printf("nvs get data:%d \n",temp);
temp++;
if ( ESP_OK != nvs_set_i32(handle, DATA1_i32, temp) )
{
printf("nvs set i32 error\n");
}
ESP_ERROR_CHECK( nvs_commit(handle) );
nvs_close(handle);
return temp;
}
3、 保存结构体
typedef struct{
uint8_t buf[10];
uint32_t val;
}str_blob_par;
str_blob_par blob_par;
void my_nvs_flash_blob_test(void)
{
nvs_handle handle;
uint32_t len ;
uint8_t i;
printf("blob test---------->\n");
ESP_ERROR_CHECK( nvs_open(NVS_CUSTOMER, NVS_READWRITE, &handle) );
memset(&blob_par, 0x0, sizeof(str_blob_par));
len = sizeof(str_blob_par);
if (ESP_OK != nvs_get_blob(handle, DATA2_blob, &blob_par, &len))
{
printf("nvs get blob error \n");
}
printf("nvs get buf[0]:%d-val:%d \n",blob_par.buf[0],blob_par.val);
for (i=0; i<10;i++)
{
blob_par.buf[i] += 1;
}
blob_par.val += 1;
ESP_ERROR_CHECK( nvs_set_blob( handle, DATA2_blob, &blob_par, sizeof(blob_par)) );
ESP_ERROR_CHECK( nvs_commit(handle) );
nvs_close(handle);
}
4、 保存字符串
char str_buf[10] ="123456789";
void my_nvs_flash_str_test(void)
{
nvs_handle handle;
int32_t result = 0;
uint32_t str_length;
printf("str test---------->\n");
printf("%s\n",str_buf);
ESP_ERROR_CHECK( nvs_open(NVS_CUSTOMER, NVS_READWRITE, &handle) );
str_length = sizeof(str_buf);
printf("str_length :%d \n",str_length);
#if 1
result = nvs_get_str(handle, DATA3_Str, str_buf, &str_length);
if (ESP_OK != result)
{
printf("nvs get str error \n");
memcpy(str_buf,"123456789",sizeof("123456789"));
}
//printf("^^:%c-%c-%c \n",str_buf[0],str_buf[1],str_buf[2]);
printf("^^:%s \n",str_buf);
if (str_buf[0] == '9')
{
str_buf[0] = '0';
}
str_buf[0] += 1;
#endif
result = nvs_set_str( handle, DATA3_Str, str_buf) ;
if (ESP_OK != result)
{
printf("nvs set str error \n");
}
ESP_ERROR_CHECK( nvs_commit(handle) );
nvs_close(handle);
}
测试效果:
长按GPIO0引脚设备会复位。