You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ESP32重启后nvs_get_blob读取自定义类实例异常

ESP32 NVS读取自定义类实例跨重启失效问题

我正在为ESP32-WROOM-32E(又称Dev-Kit-C V4)开发NVS与WiFi功能的封装库,当前按以下顺序测试:

  • 重启后直接从NVS读取并处理/打印自定义类实例的数据;
  • 每次重启后向NVS保存一个同键值的新自定义类实例;
  • 完成步骤2的保存后,立即使用步骤1的代码再次读取并处理/打印实例数据。

问题:步骤1中,开发板重启后无法从NVS正确获取自定义类实例(串口输出空的SSID和Password,但Blob大小显示为52字节),但步骤3中保存后可正常读取。测试过保存整数数组、i32等类型可跨重启正常读取,仅自定义类实例出现该问题。

串口输出如下:

Blob Size: 52
SSID: "" Password: ""
Set Blob of Key: key123
Saved Value of key123 to NVS.
Blob Size: 52
SSID: "key123" Password: "ThisIsTheNewPassword"

app_main代码

extern "C"
{
    void app_main(void);
}

#include "wholeinclude.h"
#include "nvs_wrapper.h"
#include "WiFi_Functions.h"

// #define keythatneverexists "ineverdoexist"
#define keyname "key123"

void app_main(void)
{
    vTaskDelay(4000 / portTICK_PERIOD_MS);

    esp_err_t err = nvs_flash_init();
    if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND)
    {
        ESP_ERROR_CHECK(nvs_flash_erase());
        err = nvs_flash_init();
    }
    ESP_ERROR_CHECK(err);



    WiFi_Functions::AP_Credentials *test = WiFi_Functions::AP_Credentials::getCredentialFromNVS(keyname);
    if (test)
        test->printConnectionData();
    else
        std::cout << "Key was not found directly after restart.\n";



    WiFi_Functions::AP_Credentials *test2 = new WiFi_Functions::AP_Credentials(keyname, "ThisIsTheNewPassword");
    WiFi_Functions::AP_Credentials::setCredentialToNVS(keyname, test2);



    WiFi_Functions::AP_Credentials *test3 = WiFi_Functions::AP_Credentials::getCredentialFromNVS(keyname);
    if (test3)
        test3->printConnectionData();
    else
        std::cout << "Key was found directly after Setting up.\n";
}

getCredentialFromNVS函数

WiFi_Functions::AP_Credentials *WiFi_Functions::AP_Credentials::getCredentialFromNVS(std::string wifi_ssid)
{
    WiFi_Functions::AP_Credentials* received_connection = nullptr;
    void *received_void_connection = received_connection;

    if (nvs_wrapper::getValueFromKey(wifi_ssid, received_void_connection) != ESP_OK)
    {
        std::cout << "Error during first get call.\n";
        return nullptr;
    }
    else
    {
        received_connection = (WiFi_Functions::AP_Credentials*)received_void_connection;
        return received_connection;
    }
}

getValueFromKey函数

esp_err_t nvs_wrapper::getValueFromKey(std::string key_name, void *&retrieved_value)
{

    esp_err_t err = nvs_open(nvs_namespace_name, NVS_READWRITE, &nvs_namespace_handle);
    if (err != ESP_OK)
    {
        printf("Couldn't open namespace\n");
        ESP_ERROR_CHECK_WITHOUT_ABORT(err);
        return err;
    }

    size_t required_size;

    err = nvs_get_blob(nvs_namespace_handle, key_name.c_str(), NULL, &required_size);
    if (err != ESP_OK)
    {
        printf("failed get blob size\n");

        ESP_ERROR_CHECK_WITHOUT_ABORT(err);
        nvs_close(nvs_namespace_handle);
        return err;
    }
    else
    {
        std::cout << "Blob Size: " << required_size << "\n";
    }

    retrieved_value = malloc(required_size);

    err = nvs_get_blob(nvs_namespace_handle, key_name.c_str(), retrieved_value, &required_size);

    if (err != ESP_OK)
    {
        printf("failed to get blob data\n");
        ESP_ERROR_CHECK_WITHOUT_ABORT(err);
        free(retrieved_value);
        nvs_close(nvs_namespace_handle);
        return err;
    }
    else
    {
        nvs_close(nvs_namespace_handle);
        return err;
    }
}

setCredentialToNVS函数

esp_err_t WiFi_Functions::AP_Credentials::setCredentialToNVS(std::string wifi_ssid, WiFi_Functions::AP_Credentials *cred)
{
    esp_err_t err;
    err = (nvs_wrapper::setValueToKey(wifi_ssid, cred, sizeof(*cred)));

    if (err != ESP_OK)
    {
        printf("Failed to save Value of %s to NVS.\n", cred->getWifi_ssid().c_str());
        ESP_ERROR_CHECK_WITHOUT_ABORT(err);
        return err;
    }
    printf("Saved Value of %s to NVS.\n", cred->getWifi_ssid().c_str());
    return err;
}

setValueToKey函数

esp_err_t nvs_wrapper::setValueToKey(std::string key_name, void *value, size_t blob_size)
{
    esp_err_t err = nvs_open(nvs_namespace_name, NVS_READWRITE, &nvs_namespace_handle);
    if (err != ESP_OK)
    {
        ESP_ERROR_CHECK_WITHOUT_ABORT(err);
        return err;
    }


    err = nvs_set_blob(nvs_namespace_handle, key_name.c_str(), value, blob_size);

    if (err != ESP_OK)
    {
        ESP_ERROR_CHECK_WITHOUT_ABORT(err);
        nvs_close(nvs_namespace_handle);
        return err;
    }
    else
        printf("Set Blob of Key: %s\n", key_name.c_str());

    err = nvs_commit(nvs_namespace_handle);
    if (err != ESP_OK)
    {
        ESP_ERROR_CHECK_WITHOUT_ABORT(err);
        nvs_close(nvs_namespace_handle);
        return err;
    }
    nvs_close(nvs_namespace_handle);
    return err;
}

内容的提问来源于stack exchange,提问作者Gisbert12843

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 18:05:59