ESP32 Use NVS directly (#659)

This commit is contained in:
Otto Winter 2019-07-03 16:34:40 +02:00 committed by GitHub
parent 0ef1d178d2
commit 81a070d03d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 51 additions and 19 deletions

View file

@ -40,7 +40,7 @@ class Application {
void pre_setup(const std::string &name, const char *compilation_time) { void pre_setup(const std::string &name, const char *compilation_time) {
this->name_ = name; this->name_ = name;
this->compilation_time_ = compilation_time; this->compilation_time_ = compilation_time;
global_preferences.begin(this->name_); global_preferences.begin();
} }
#ifdef USE_BINARY_SENSOR #ifdef USE_BINARY_SENSOR

View file

@ -1,12 +1,17 @@
#include "esphome/core/preferences.h" #include "esphome/core/preferences.h"
#include "esphome/core/log.h" #include "esphome/core/log.h"
#include "esphome/core/helpers.h" #include "esphome/core/helpers.h"
#include "esphome/core/application.h"
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
extern "C" { extern "C" {
#include "spi_flash.h" #include "spi_flash.h"
} }
#endif #endif
#ifdef ARDUINO_ARCH_ESP32
#include "nvs.h"
#include "nvs_flash.h"
#endif
namespace esphome { namespace esphome {
@ -165,7 +170,7 @@ ESPPreferences::ESPPreferences()
// which will be reset each time OTA occurs // which will be reset each time OTA occurs
: current_offset_(0) {} : current_offset_(0) {}
void ESPPreferences::begin(const std::string &name) { void ESPPreferences::begin() {
this->flash_storage_ = new uint32_t[ESP8266_FLASH_STORAGE_SIZE]; this->flash_storage_ = new uint32_t[ESP8266_FLASH_STORAGE_SIZE];
ESP_LOGVV(TAG, "Loading preferences from flash..."); ESP_LOGVV(TAG, "Loading preferences from flash...");
disable_interrupts(); disable_interrupts();
@ -219,32 +224,64 @@ bool ESPPreferences::is_prevent_write() { return this->prevent_write_; }
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
bool ESPPreferenceObject::save_internal_() { bool ESPPreferenceObject::save_internal_() {
if (global_preferences.nvs_handle_ == 0)
return false;
char key[32]; char key[32];
sprintf(key, "%u", this->offset_); sprintf(key, "%u", this->offset_);
uint32_t len = (this->length_words_ + 1) * 4; uint32_t len = (this->length_words_ + 1) * 4;
size_t ret = global_preferences.preferences_.putBytes(key, this->data_, len); esp_err_t err = nvs_set_blob(global_preferences.nvs_handle_, key, this->data_, len);
if (ret != len) { if (err) {
ESP_LOGV(TAG, "putBytes failed!"); ESP_LOGV(TAG, "nvs_set_blob('%s', len=%u) failed: %s", key, len, esp_err_to_name(err));
return false;
}
err = nvs_commit(global_preferences.nvs_handle_);
if (err) {
ESP_LOGV(TAG, "nvs_commit('%s', len=%u) failed: %s", key, len, esp_err_to_name(err));
return false; return false;
} }
return true; return true;
} }
bool ESPPreferenceObject::load_internal_() { bool ESPPreferenceObject::load_internal_() {
if (global_preferences.nvs_handle_ == 0)
return false;
char key[32]; char key[32];
sprintf(key, "%u", this->offset_); sprintf(key, "%u", this->offset_);
uint32_t len = (this->length_words_ + 1) * 4; uint32_t len = (this->length_words_ + 1) * 4;
size_t ret = global_preferences.preferences_.getBytes(key, this->data_, len);
if (ret != len) { uint32_t actual_len;
ESP_LOGV(TAG, "getBytes failed!"); esp_err_t err = nvs_get_blob(global_preferences.nvs_handle_, key, nullptr, &actual_len);
if (err) {
ESP_LOGV(TAG, "nvs_get_blob('%s'): %s - the key might not be set yet", key, esp_err_to_name(err));
return false;
}
if (actual_len != len) {
ESP_LOGVV(TAG, "NVS length does not match. Assuming key changed (%u!=%u)", actual_len, len);
return false;
}
err = nvs_get_blob(global_preferences.nvs_handle_, key, this->data_, &len);
if (err) {
ESP_LOGV(TAG, "nvs_get_blob('%s') failed: %s", key, esp_err_to_name(err));
return false; return false;
} }
return true; return true;
} }
ESPPreferences::ESPPreferences() : current_offset_(0) {} ESPPreferences::ESPPreferences() : current_offset_(0) {}
void ESPPreferences::begin(const std::string &name) { void ESPPreferences::begin() {
const std::string key = truncate_string(name, 15); auto ns = truncate_string(App.get_name(), 15);
ESP_LOGV(TAG, "Opening preferences with key '%s'", key.c_str()); esp_err_t err = nvs_open(ns.c_str(), NVS_READWRITE, &this->nvs_handle_);
this->preferences_.begin(key.c_str()); if (err) {
ESP_LOGW(TAG, "nvs_open failed: %s - erasing NVS...", esp_err_to_name(err));
nvs_flash_deinit();
nvs_flash_erase();
nvs_flash_init();
err = nvs_open(ns.c_str(), NVS_READWRITE, &this->nvs_handle_);
if (err) {
this->nvs_handle_ = 0;
}
}
} }
ESPPreferenceObject ESPPreferences::make_preference(size_t length, uint32_t type, bool in_flash) { ESPPreferenceObject ESPPreferences::make_preference(size_t length, uint32_t type, bool in_flash) {

View file

@ -2,10 +2,6 @@
#include <string> #include <string>
#ifdef ARDUINO_ARCH_ESP32
#include <Preferences.h>
#endif
#include "esphome/core/esphal.h" #include "esphome/core/esphal.h"
#include "esphome/core/defines.h" #include "esphome/core/defines.h"
@ -56,7 +52,7 @@ static bool DEFAULT_IN_FLASH = true;
class ESPPreferences { class ESPPreferences {
public: public:
ESPPreferences(); ESPPreferences();
void begin(const std::string &name); void begin();
ESPPreferenceObject make_preference(size_t length, uint32_t type, bool in_flash = DEFAULT_IN_FLASH); ESPPreferenceObject make_preference(size_t length, uint32_t type, bool in_flash = DEFAULT_IN_FLASH);
template<typename T> ESPPreferenceObject make_preference(uint32_t type, bool in_flash = DEFAULT_IN_FLASH); template<typename T> ESPPreferenceObject make_preference(uint32_t type, bool in_flash = DEFAULT_IN_FLASH);
@ -77,7 +73,7 @@ class ESPPreferences {
uint32_t current_offset_; uint32_t current_offset_;
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
Preferences preferences_; uint32_t nvs_handle_;
#endif #endif
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
void save_esp8266_flash_(); void save_esp8266_flash_();

View file

@ -239,7 +239,6 @@ def to_code(config):
# Libraries # Libraries
if CORE.is_esp32: if CORE.is_esp32:
cg.add_library('Preferences', None)
cg.add_library('ESPmDNS', None) cg.add_library('ESPmDNS', None)
elif CORE.is_esp8266: elif CORE.is_esp8266:
cg.add_library('ESP8266WiFi', None) cg.add_library('ESP8266WiFi', None)