mirror of
https://github.com/esphome/esphome.git
synced 2025-09-29 08:32:26 +01:00
ESP-IDF support and generic target platforms (#2303)
* Socket refactor and SSL * esp-idf temp * Fixes * Echo component and noise * Add noise API transport support * Updates * ESP-IDF * Complete * Fixes * Fixes * Versions update * New i2c APIs * Complete i2c refactor * SPI migration * Revert ESP Preferences migration, too complex for now * OTA support * Remove echo again * Remove ssl again * GPIOFlags updates * Rename esphal and ICACHE_RAM_ATTR * Make ESP32 arduino compilable again * Fix GPIO flags * Complete pin registry refactor and fixes * Fixes to make test1 compile * Remove sdkconfig file * Ignore sdkconfig file * Fixes in reviewing * Make test2 compile * Make test4 compile * Make test5 compile * Run clang-format * Fix lint errors * Use esp-idf APIs instead of btStart * Another round of fixes * Start implementing ESP8266 * Make test3 compile * Guard esp8266 code * Lint * Reformat * Fixes * Fixes v2 * more fixes * ESP-IDF tidy target * Convert ARDUINO_ARCH_ESPxx * Update WiFiSignalSensor * Update time ifdefs * OTA needs millis from hal * RestartSwitch needs delay from hal * ESP-IDF Uart * Fix OTA blank password * Allow setting sdkconfig * Fix idf partitions and allow setting sdkconfig from yaml * Re-add read/write compat APIs and fix esp8266 uart * Fix esp8266 store log strings in flash * Fix ESP32 arduino preferences not initialized * Update ifdefs * Change how sdkconfig change is detected * Add checks to ci-custom and fix them * Run clang-format * Add esp-idf clang-tidy target and fix errors * Fixes from clang-tidy idf round 2 * Fixes from compiling tests with esp-idf * Run clang-format * Switch test5.yaml to esp-idf * Implement ESP8266 Preferences * Lint * Re-do PIO package version selection a bit * Fix arduinoespressif32 package version * Fix unit tests * Lint * Lint fixes * Fix readv/writev not defined * Fix graphing component * Re-add all old options from core/config.py Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
@@ -1,112 +1,61 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
#include "esphome/core/defines.h"
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
namespace esphome {
|
||||
|
||||
class ESPPreferenceBackend {
|
||||
public:
|
||||
virtual bool save(const uint8_t *data, size_t len) = 0;
|
||||
virtual bool load(uint8_t *data, size_t len) = 0;
|
||||
};
|
||||
|
||||
class ESPPreferenceObject {
|
||||
public:
|
||||
ESPPreferenceObject() = default;
|
||||
ESPPreferenceObject(size_t offset, size_t length, uint32_t type);
|
||||
ESPPreferenceObject(ESPPreferenceBackend *backend) : backend_(backend) {}
|
||||
|
||||
template<typename T> bool save(T *src);
|
||||
template<typename T> bool save(const T *src) {
|
||||
if (backend_ == nullptr)
|
||||
return false;
|
||||
return backend_->save(reinterpret_cast<const uint8_t *>(src), sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T> bool load(T *dest);
|
||||
|
||||
bool is_initialized() const;
|
||||
template<typename T> bool load(T *dest) {
|
||||
if (backend_ == nullptr)
|
||||
return false;
|
||||
return backend_->load(reinterpret_cast<uint8_t *>(dest), sizeof(T));
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class ESPPreferences;
|
||||
|
||||
bool save_();
|
||||
bool load_();
|
||||
bool save_internal_();
|
||||
bool load_internal_();
|
||||
|
||||
uint32_t calculate_crc_() const;
|
||||
|
||||
size_t offset_ = 0;
|
||||
size_t length_words_ = 0;
|
||||
uint32_t type_ = 0;
|
||||
std::vector<uint32_t> data_;
|
||||
#ifdef ARDUINO_ARCH_ESP8266
|
||||
bool in_flash_ = false;
|
||||
#endif
|
||||
ESPPreferenceBackend *backend_;
|
||||
};
|
||||
|
||||
#ifdef ARDUINO_ARCH_ESP8266
|
||||
#ifdef USE_ESP8266_PREFERENCES_FLASH
|
||||
static const bool DEFAULT_IN_FLASH = true;
|
||||
#else
|
||||
static const bool DEFAULT_IN_FLASH = false;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
static const bool DEFAULT_IN_FLASH = true;
|
||||
#endif
|
||||
|
||||
class ESPPreferences {
|
||||
public:
|
||||
ESPPreferences();
|
||||
void begin();
|
||||
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);
|
||||
|
||||
#ifdef ARDUINO_ARCH_ESP8266
|
||||
/** On the ESP8266, we can't override the first 128 bytes during OTA uploads
|
||||
* as the eboot parameters are stored there. Writing there during an OTA upload
|
||||
* would invalidate applying the new firmware. During normal operation, we use
|
||||
* this part of the RTC user memory, but stop writing to it during OTA uploads.
|
||||
*
|
||||
* @param prevent Whether to prevent writing to the first 32 words of RTC user memory.
|
||||
*/
|
||||
void prevent_write(bool prevent);
|
||||
bool is_prevent_write();
|
||||
virtual ESPPreferenceObject make_preference(size_t length, uint32_t type, bool in_flash) = 0;
|
||||
virtual ESPPreferenceObject make_preference(size_t length, uint32_t type) = 0;
|
||||
#ifndef USE_ESP8266
|
||||
template<typename T, typename std::enable_if<std::is_trivially_copyable<T>::value, bool>::type = true>
|
||||
#else
|
||||
// esp8266 toolchain doesn't have is_trivially_copyable
|
||||
template<typename T>
|
||||
#endif
|
||||
|
||||
protected:
|
||||
friend ESPPreferenceObject;
|
||||
|
||||
uint32_t current_offset_;
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
uint32_t nvs_handle_;
|
||||
#endif
|
||||
#ifdef ARDUINO_ARCH_ESP8266
|
||||
void save_esp8266_flash_();
|
||||
bool prevent_write_{false};
|
||||
uint32_t *flash_storage_;
|
||||
uint32_t current_flash_offset_;
|
||||
ESPPreferenceObject make_preference(uint32_t type, bool in_flash) {
|
||||
return this->make_preference(sizeof(T), type, in_flash);
|
||||
}
|
||||
#ifndef USE_ESP8266
|
||||
template<typename T, typename std::enable_if<std::is_trivially_copyable<T>::value, bool>::type = true>
|
||||
#else
|
||||
template<typename T>
|
||||
#endif
|
||||
ESPPreferenceObject make_preference(uint32_t type) {
|
||||
return this->make_preference(sizeof(T), type);
|
||||
}
|
||||
};
|
||||
|
||||
extern ESPPreferences global_preferences; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
|
||||
template<typename T> ESPPreferenceObject ESPPreferences::make_preference(uint32_t type, bool in_flash) {
|
||||
return this->make_preference((sizeof(T) + 3) / 4, type, in_flash);
|
||||
}
|
||||
|
||||
template<typename T> bool ESPPreferenceObject::save(T *src) {
|
||||
if (!this->is_initialized())
|
||||
return false;
|
||||
// ensure all bytes are 0 (in case sizeof(T) is not multiple of 4)
|
||||
std::fill_n(data_.begin(), length_words_, 0);
|
||||
memcpy(data_.data(), src, sizeof(T));
|
||||
return this->save_();
|
||||
}
|
||||
|
||||
template<typename T> bool ESPPreferenceObject::load(T *dest) {
|
||||
std::fill_n(data_.begin(), length_words_, 0);
|
||||
if (!this->load_())
|
||||
return false;
|
||||
|
||||
memcpy(dest, data_.data(), sizeof(T));
|
||||
return true;
|
||||
}
|
||||
extern ESPPreferences *global_preferences; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
|
||||
} // namespace esphome
|
||||
|
Reference in New Issue
Block a user