Advertisement

ESP32 NVS 非易失性存储

阅读量:

简介

非易失性存储 (NVS) 库主要用于在 flash 中存储键值格式 的数据。

本章节采用NVS存储WIFI的账户和密码信息。

本章涉及核心知识点:NVS掉电不丢失存储系统。

ESP-IDF版本:V5.1.2

源码

小智学长的源码:Docs

程序实现

NVS实现的核心步骤:

1.nvs_flash_init() NVS初始化

2.nvs_open(const char* namespace_name, nvs_open_mode_t open_mode, nvs_handle_t *out_handle) 打开NVS存储区,创建文件夹,文件夹的名字为namespace_name指针所指向的名字,并赋予其打开模式,以及传递给句柄

3.设置数据或者获取数据,例nvs_get_u32或nvs_set_u32,该函数需要根据具体的参数类型进行匹配设定

4.递交 nvs_commit(nvs_handle_t c_handle) 句柄为创建时的句柄,该步骤确保之前设定的数据提交到nvs中

5.关闭nvs_close(nvs_handle_t handle) 句柄为创建时的句柄

6.销毁(若需要)

首先,创建全局枚举变量,用于反馈NVS状态是错误、空或存储。

创建nvs存储函数、nvs读取函数、以及nvs初始化函数。

复制代码
 static const char *TAG = "ds_nvs";

    
  
    
 typedef enum{
    
     NVS_WIFI_INFO_ERROR =0,
    
     NVS_WIFI_INFO_NULL,
    
     NVS_WIFI_INFO_SAVE,
    
 }NVS_WIFI_INFO_E;
    
  
    
 NVS_WIFI_INFO_E wifi_config_flag = NVS_WIFI_INFO_NULL;  //创建全局枚举变量wifi_config
    
  
    
 void ds_nvs_save_wifi_info(){
    
     esp_err_t err;
    
     nvs_handle_t nvs_handle;
    
     err = nvs_open("wificonfig", NVS_READWRITE, &nvs_handle); //打开wificondig存储区,可读可写,成功返回到nvs_handle句柄
    
     if (err != ESP_OK) {
    
     ESP_LOGI(TAG,"Error (%s) opening NVS handle!\n", esp_err_to_name(err));
    
     return ;
    
     }
    
     wifi_config_flag = NVS_WIFI_INFO_SAVE;
    
     ESP_ERROR_CHECK(nvs_set_u8(nvs_handle, "wifi_flag", wifi_config_flag)); //设置wifi标志
    
     ESP_ERROR_CHECK(nvs_set_str(nvs_handle, "ssid", get_system_data().setting_ssid));   //设置wifi账号
    
     ESP_ERROR_CHECK(nvs_set_str(nvs_handle, "psw",  get_system_data().setting_psw));    //设置wifi密码
    
     ESP_ERROR_CHECK(nvs_commit(nvs_handle));    //确保将更改的数据写入nvs中
    
     nvs_close(nvs_handle);  //关闭句柄
    
 }
    
  
    
 NVS_WIFI_INFO_E ds_nvs_read_wifi_info(){
    
     esp_err_t err;
    
     nvs_handle_t nvs_handle;
    
     err = nvs_open("wificonfig", NVS_READWRITE, &nvs_handle); 
    
     if (err != ESP_OK) {
    
     ESP_LOGI(TAG,"Error (%s) opening NVS handle!\n", esp_err_to_name(err));
    
     return NVS_WIFI_INFO_ERROR;
    
     }
    
     uint8_t wifi_config = 0;
    
     ESP_ERROR_CHECK(nvs_get_u8(nvs_handle, "wifi_flag", &wifi_config)); //nvs_handle句柄,wifi_config键值,读取数据存储到wifi_config变量中
    
     wifi_config_flag = wifi_config; //将局部变量wifi_config的值传递给全局变量wifi_config_flag
    
     if(wifi_config_flag == NVS_WIFI_INFO_SAVE){
    
     ESP_LOGI(TAG,"has wifi config info");
    
     char ssid[32];
    
     char psw[64];
    
     size_t ssid_len = sizeof(ssid);
    
     size_t psw_len = sizeof(psw);
    
     ESP_ERROR_CHECK(nvs_get_str(nvs_handle, "ssid", ssid, &ssid_len));  //指定nvs_handle句柄,key值,存储地址,长度
    
     ESP_ERROR_CHECK(nvs_get_str(nvs_handle, "psw", psw, &psw_len));
    
     set_system_data_wifi_info(ssid,ssid_len,psw,psw_len);
    
     print_system_data_wifi_info();
    
     }else{
    
     ESP_LOGI(TAG,"wifi config info null");
    
     }
    
     nvs_close(nvs_handle);
    
     return wifi_config_flag;
    
 }
    
  
    
 void ds_nvs_init(){
    
     // 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 );
    
 }
    
    
    
    
复制代码
 #include <string.h>

    
 #include "sdkconfig.h"
    
 #include "esp_system.h"
    
 #include "esp_log.h"
    
 #include "print_wifi_data.h"
    
  
    
 static const char *TAG = "ds_system_data";
    
  
    
 SYSTRM_DATA_T g_system_data;
    
  
    
 void ds_system_data_init(){
    
     memset(&g_system_data,0,sizeof(SYSTRM_DATA_T));
    
 }
    
  
    
 //创建该函数是为了让其能在其他文件调用该结构体
    
 SYSTRM_DATA_T get_system_data(){
    
     return g_system_data;
    
 }
    
  
    
 //保存数据到g_system_data结构体中
    
 void set_system_data_wifi_info(char * p_ssid,uint8_t p_ssidlen,char *p_psw ,uint8_t p_pswlen){
    
     if(p_pswlen >= MAX_SETTING_SSID_LEN || p_ssidlen >= MAX_SETTING_PSW_LEN){
    
     ESP_LOGE(TAG, "MAX_SETTING_SSID_PWD_LEN ERROR");
    
     }
    
     g_system_data.setting_ssid_len = p_ssidlen;
    
     g_system_data.setting_psw_len = p_pswlen;
    
     memcpy(g_system_data.setting_ssid,p_ssid,p_ssidlen);
    
     memcpy(g_system_data.setting_psw,p_psw,p_pswlen);
    
     g_system_data.setting_ssid[p_ssidlen] = '\0';
    
     g_system_data.setting_psw[p_pswlen] = '\0';
    
 }
    
  
    
 void print_system_data_wifi_info(){
    
     printf("\r\nwifi_ssid:");
    
     for(int i = 0;i<g_system_data.setting_ssid_len;i++){
    
     printf("%c",g_system_data.setting_ssid[i]);
    
     }
    
  
    
     printf("\r\nwifi_password:");
    
     for(int i = 0;i<g_system_data.setting_psw_len;i++){
    
     printf("%c",g_system_data.setting_psw[i]);
    
     }
    
     printf("\r\n");
    
 }
    
  
    
 SETTING_DATA_E check_system_data_wifi_info(){
    
     if(g_system_data.setting_ssid_len != 0){
    
     return SETTING_DATA_HAS_WIFI_INFO;
    
     }
    
     return SETTING_DATA_INIT;
    
 }
    
    
    
    

学习资源

此处推荐孤独的二进制NVS的学习,很不错!

ESP32 存储篇 NVS 非易失性存储库 - 乐鑫 ESP32 物联网开发框架 ESP-IDF 开发入门 - 孤独的二进制出品_哔哩哔哩_bilibili

全部评论 (0)

还没有任何评论哟~