在 ESP—IDF上编写Esp32C3之NVS非易失性存储(二)

1.NVS是什么以及作用是什么?

                NVS总的来说,就是非易失性存储,类似MCU EEPROM   表和键值相对应,表为句柄。利用句柄找对应的key值

                NVS用于在flash 中存储字符串,将字符串转换成数值存储,比如ESP要存储wifi的名字和密码,以及每次上电连上上一次的WIFI,以及改变WIFI后保存相关信息。

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "nvs.h"


void setup() {

    //01 初始化nvs flash
    esp_err_t err = nvs_flash_init();                                                        //   初始化 NVS 分区

    //02 如果nvs flash 满了就清空   如果失败可调用“nvs_flash_erase()”擦除NVS,然后再次初始化。
    if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        ESP_ERROR_CHECK(nvs_flash_erase());                                                  //   擦除 nvs 分区
        err = nvs_flash_init();
    }
    ESP_ERROR_CHECK(err);




    //03 打开nvs,配置句柄
    printf("\n");
    printf("Opening Non-Volatile Storage (NVS) handle... ");
    nvs_handle my_handle;                                                                     //配置 my_handle 名字的空间名  一个表


/*           nvs_open 
 *           对表的属性进行赋属性,获取NVS空间的操作句柄
 *           打开一个表 
 *           第一个形参为一个字符串,可称为表名。
 *           第二个是读写模式,可选读写或者只读
 *           第三个是当前打开的表的句柄  
*/
    err = nvs_open("storage", NVS_READWRITE, &my_handle);    
    if (err != ESP_OK) {
        printf("Error (%s) opening NVS handle!\n", esp_err_to_name(err));   
    }
    else {
        printf("Done\n");




        //04 读操作
        printf("Reading restart counter from NVS ... ");
        int32_t restart_counter = 0; 
        // 如果没有在nvs中设置,则值默认为0



/*           nvs_get_i32 
 *           读取函数: 利用表去找对应的值
 *           打开一个表 
 *           第一个是表的句柄
 *           第二个是键值
 *           第三个则是对应的变量的指针 
*/

        err = nvs_get_i32(my_handle, "restart_counter", &restart_counter);              //读取函数 
        switch (err) {
        case ESP_OK:
            printf("Done\n");
            printf("Restart counter = %ld\n", restart_counter);
            break;
        case ESP_ERR_NVS_NOT_FOUND:
            printf("The value is not initialized yet!\n");
            break;
        default:
            printf("Error (%s) reading!\n", esp_err_to_name(err));
        }

        //05 写操作
        printf("Updating restart counter in NVS ... ");
        restart_counter++;
        err = nvs_set_i32(my_handle, "restart_counter", restart_counter);
        printf((err != ESP_OK) ? "Failed!\n" : "Done\n");

        //06 提交修改
        printf("Committing updates in NVS ... ");
        err = nvs_commit(my_handle);
        printf((err != ESP_OK) ? "Failed!\n" : "Done\n");

        //07 关闭nvs
        nvs_close(my_handle);
    }

    printf("\n");

    // 定时重启模块
    for (int i = 10; i >= 0; i--) {
        printf("Restarting in %d seconds...\n", i);
        vTaskDelay(1000 / portTICK_PERIOD_MS);                                  //  延时
    }
    printf("Restarting now.\n");
    fflush(stdout);
    esp_restart();

}

void app_main()
{
    printf("main");
    setup();

}

NVS相关API使用方法如下:

(1)初始化

         调用“nvs_flash_init();”,如果失败可调用“nvs_flash_erase()”擦除NVS,然后再次初始化。

(2)打开一个表

       

    nvs_open("List", NVS_READWRITE, &my_handle);
        这个API第一个形参为一个字符串,可称为表名。第二个是读写模式,可选读写或者只读,第三个是当前打开的表的句柄。

        如此声明:“nvs_handle my_handle;   ”。后面对表里面的键值进行读写,都需要输入键值所在表的句柄。

(3)读写

         读:

    vs_get_i8(my_handle, "nvs_i8", &nvs_i8);
         读写不同的数据类型需要调用不同的API,类似的API有:“nvs_get_i16”,“nvs_get_u32”等等

         形参方面,第一个是表的句柄,第二个是键值,第三个则是对应的变量的指针,如“nvs_i8”是个“int8_t”类型的变量。

         写:

   nvs_set_i8(my_handle, "nvs_i8", nvs_i8);
         基本跟读差不多,注意的是第三个形参变成了对应的变量,而不是变量的指针。

 (4)提交与关闭

          提交:

    nvs_commit(my_handle);
          关闭:

    nvs_close(my_handle);

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值