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
相关产品推荐
相关产品推荐

