1
0
mirror of https://github.com/esphome/esphome.git synced 2025-10-29 14:13:51 +00:00

Configurable Flash Write Interval (#2119)

Co-authored-by: Alex <33379584+alexyao2015@users.noreply.github.com>
Co-authored-by: Otto winter <otto@otto-winter.com>
This commit is contained in:
Alex
2021-09-21 06:47:51 -05:00
committed by GitHub
parent 71fc61117b
commit 491f8cc611
10 changed files with 160 additions and 41 deletions

View File

@@ -23,6 +23,7 @@ from .gpio import esp8266_pin_to_code # noqa
CODEOWNERS = ["@esphome/core"]
_LOGGER = logging.getLogger(__name__)
AUTO_LOAD = ["preferences"]
def set_core_data(config):

View File

@@ -73,33 +73,7 @@ template<class It> uint32_t calculate_crc(It first, It last, uint32_t type) {
return crc;
}
static bool safe_flash() {
if (!s_flash_dirty)
return true;
ESP_LOGVV(TAG, "Saving preferences to flash...");
SpiFlashOpResult erase_res, write_res = SPI_FLASH_RESULT_OK;
{
InterruptLock lock;
erase_res = spi_flash_erase_sector(get_esp8266_flash_sector());
if (erase_res == SPI_FLASH_RESULT_OK) {
write_res = spi_flash_write(get_esp8266_flash_address(), s_flash_storage, ESP8266_FLASH_STORAGE_SIZE * 4);
}
}
if (erase_res != SPI_FLASH_RESULT_OK) {
ESP_LOGV(TAG, "Erase ESP8266 flash failed!");
return false;
}
if (write_res != SPI_FLASH_RESULT_OK) {
ESP_LOGV(TAG, "Write ESP8266 flash failed!");
return false;
}
s_flash_dirty = false;
return true;
}
static bool safe_to_flash(size_t offset, const uint32_t *data, size_t len) {
static bool save_to_flash(size_t offset, const uint32_t *data, size_t len) {
for (uint32_t i = 0; i < len; i++) {
uint32_t j = offset + i;
if (j >= ESP8266_FLASH_STORAGE_SIZE)
@@ -110,7 +84,7 @@ static bool safe_to_flash(size_t offset, const uint32_t *data, size_t len) {
s_flash_dirty = true;
*ptr = v;
}
return safe_flash();
return true;
}
static bool load_from_flash(size_t offset, uint32_t *data, size_t len) {
@@ -123,7 +97,7 @@ static bool load_from_flash(size_t offset, uint32_t *data, size_t len) {
return true;
}
static bool safe_to_rtc(size_t offset, const uint32_t *data, size_t len) {
static bool save_to_rtc(size_t offset, const uint32_t *data, size_t len) {
for (uint32_t i = 0; i < len; i++)
if (!esp_rtc_user_mem_write(offset + i, data[i]))
return false;
@@ -154,9 +128,9 @@ class ESP8266PreferenceBackend : public ESPPreferenceBackend {
buffer[buffer.size() - 1] = calculate_crc(buffer.begin(), buffer.end() - 1, type);
if (in_flash) {
return safe_to_flash(offset, buffer.data(), buffer.size());
return save_to_flash(offset, buffer.data(), buffer.size());
} else {
return safe_to_rtc(offset, buffer.data(), buffer.size());
return save_to_rtc(offset, buffer.data(), buffer.size());
}
}
bool load(uint8_t *data, size_t len) override {
@@ -245,6 +219,34 @@ class ESP8266Preferences : public ESPPreferences {
return make_preference(length, type, false);
#endif
}
bool sync() override {
if (!s_flash_dirty)
return true;
if (s_prevent_write)
return false;
ESP_LOGD(TAG, "Saving preferences to flash...");
SpiFlashOpResult erase_res, write_res = SPI_FLASH_RESULT_OK;
{
InterruptLock lock;
erase_res = spi_flash_erase_sector(get_esp8266_flash_sector());
if (erase_res == SPI_FLASH_RESULT_OK) {
write_res = spi_flash_write(get_esp8266_flash_address(), s_flash_storage, ESP8266_FLASH_STORAGE_SIZE * 4);
}
}
if (erase_res != SPI_FLASH_RESULT_OK) {
ESP_LOGV(TAG, "Erase ESP8266 flash failed!");
return false;
}
if (write_res != SPI_FLASH_RESULT_OK) {
ESP_LOGV(TAG, "Write ESP8266 flash failed!");
return false;
}
s_flash_dirty = false;
return true;
}
};
void setup_preferences() {