From aadbc41d6ae2c90ce6f4801eb5ca5e8badaa01ac Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 3 Sep 2025 22:16:41 -0500 Subject: [PATCH 1/4] Revert "preen" This reverts commit da9a7c41d157e2f7886262989be676d6af70e71c. --- esphome/core/macros.h | 11 ----------- esphome/cpp_helpers.py | 7 +++++-- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/esphome/core/macros.h b/esphome/core/macros.h index 0f0d556616..8b2383321b 100644 --- a/esphome/core/macros.h +++ b/esphome/core/macros.h @@ -6,14 +6,3 @@ #ifdef USE_ARDUINO #include #endif - -// Portable PROGMEM string macro -// On ESP8266, PSTR() stores strings in flash memory -// On other platforms, it's a no-op -#ifndef ESPHOME_PSTR -#ifdef USE_ESP8266 -#define ESPHOME_PSTR(x) PSTR(x) -#else -#define ESPHOME_PSTR(x) (x) -#endif -#endif diff --git a/esphome/cpp_helpers.py b/esphome/cpp_helpers.py index 26a7084010..5164923b2d 100644 --- a/esphome/cpp_helpers.py +++ b/esphome/cpp_helpers.py @@ -76,8 +76,11 @@ async def register_component(var, config): "Error while finding name of component, please report this", exc_info=e ) if name is not None: - # Use ESPHOME_PSTR macro which stores strings in PROGMEM on ESP8266, no-op on other platforms - add(var.set_component_source(RawExpression(f'ESPHOME_PSTR("{name}")'))) + # On ESP8266, store component source strings in PROGMEM to save RAM + if CORE.is_esp8266: + add(var.set_component_source(RawExpression(f'PSTR("{name}")'))) + else: + add(var.set_component_source(name)) add(App.register_component(var)) return var From c57631394c58ce847861e5d34aa98d9a8dfec799 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 3 Sep 2025 22:16:59 -0500 Subject: [PATCH 2/4] Revert "[esp8266] Store component source strings in PROGMEM to save RAM" This reverts commit ea01cc598bc5cbd1f2d242783120a54f76a7106b. --- esphome/core/component.cpp | 15 --------------- esphome/cpp_helpers.py | 8 ++------ 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/esphome/core/component.cpp b/esphome/core/component.cpp index ca8d31e922..40cda17ca3 100644 --- a/esphome/core/component.cpp +++ b/esphome/core/component.cpp @@ -12,9 +12,6 @@ #ifdef USE_RUNTIME_STATS #include "esphome/components/runtime_stats/runtime_stats.h" #endif -#ifdef USE_ESP8266 -#include -#endif namespace esphome { @@ -188,19 +185,7 @@ void Component::call() { const char *Component::get_component_source() const { if (this->component_source_ == nullptr) return ""; -#ifdef USE_ESP8266 - // On ESP8266, component_source_ is stored in PROGMEM - // We need a static buffer to hold the string when read from flash - // Since this is only used for logging, a single shared buffer is fine - static char buffer[64]; // Component names are typically short - - // Copy from PROGMEM to buffer - strncpy_P(buffer, this->component_source_, sizeof(buffer) - 1); - buffer[sizeof(buffer) - 1] = '\0'; // Ensure null termination - return buffer; -#else return this->component_source_; -#endif } bool Component::should_warn_of_blocking(uint32_t blocking_time) { if (blocking_time > this->warn_if_blocking_over_) { diff --git a/esphome/cpp_helpers.py b/esphome/cpp_helpers.py index 5164923b2d..b61b215bdc 100644 --- a/esphome/cpp_helpers.py +++ b/esphome/cpp_helpers.py @@ -9,7 +9,7 @@ from esphome.const import ( ) from esphome.core import CORE, ID, coroutine from esphome.coroutine import FakeAwaitable -from esphome.cpp_generator import RawExpression, add, get_variable +from esphome.cpp_generator import add, get_variable from esphome.cpp_types import App from esphome.types import ConfigFragmentType, ConfigType from esphome.util import Registry, RegistryEntry @@ -76,11 +76,7 @@ async def register_component(var, config): "Error while finding name of component, please report this", exc_info=e ) if name is not None: - # On ESP8266, store component source strings in PROGMEM to save RAM - if CORE.is_esp8266: - add(var.set_component_source(RawExpression(f'PSTR("{name}")'))) - else: - add(var.set_component_source(name)) + add(var.set_component_source(name)) add(App.register_component(var)) return var From 897bb4d13ffa6b4fa0e50947981c69dd999f0359 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 3 Sep 2025 22:53:24 -0500 Subject: [PATCH 3/4] [esp8266] Store GPIO initialization arrays in PROGMEM to save RAM --- esphome/components/esp8266/core.cpp | 4 ++-- esphome/components/esp8266/core.h | 5 +++-- esphome/components/esp8266/gpio.py | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/esphome/components/esp8266/core.cpp b/esphome/components/esp8266/core.cpp index 2d3959b031..07659b34c8 100644 --- a/esphome/components/esp8266/core.cpp +++ b/esphome/components/esp8266/core.cpp @@ -58,8 +58,8 @@ extern "C" void resetPins() { // NOLINT #ifdef USE_ESP8266_EARLY_PIN_INIT for (int i = 0; i < 16; i++) { - uint8_t mode = ESPHOME_ESP8266_GPIO_INITIAL_MODE[i]; - uint8_t level = ESPHOME_ESP8266_GPIO_INITIAL_LEVEL[i]; + uint8_t mode = pgm_read_byte(&ESPHOME_ESP8266_GPIO_INITIAL_MODE[i]); + uint8_t level = pgm_read_byte(&ESPHOME_ESP8266_GPIO_INITIAL_LEVEL[i]); if (mode != 255) pinMode(i, mode); // NOLINT if (level != 255) diff --git a/esphome/components/esp8266/core.h b/esphome/components/esp8266/core.h index ac33305669..6daf0fd110 100644 --- a/esphome/components/esp8266/core.h +++ b/esphome/components/esp8266/core.h @@ -3,9 +3,10 @@ #ifdef USE_ESP8266 #include +#include -extern const uint8_t ESPHOME_ESP8266_GPIO_INITIAL_MODE[16]; -extern const uint8_t ESPHOME_ESP8266_GPIO_INITIAL_LEVEL[16]; +extern const uint8_t ESPHOME_ESP8266_GPIO_INITIAL_MODE[16] PROGMEM; +extern const uint8_t ESPHOME_ESP8266_GPIO_INITIAL_LEVEL[16] PROGMEM; namespace esphome { namespace esp8266 {} // namespace esp8266 diff --git a/esphome/components/esp8266/gpio.py b/esphome/components/esp8266/gpio.py index 2bc2291117..e7492fc505 100644 --- a/esphome/components/esp8266/gpio.py +++ b/esphome/components/esp8266/gpio.py @@ -199,11 +199,11 @@ async def add_pin_initial_states_array(): cg.add_global( cg.RawExpression( - f"const uint8_t ESPHOME_ESP8266_GPIO_INITIAL_MODE[16] = {{{initial_modes_s}}}" + f"const uint8_t ESPHOME_ESP8266_GPIO_INITIAL_MODE[16] PROGMEM = {{{initial_modes_s}}}" ) ) cg.add_global( cg.RawExpression( - f"const uint8_t ESPHOME_ESP8266_GPIO_INITIAL_LEVEL[16] = {{{initial_levels_s}}}" + f"const uint8_t ESPHOME_ESP8266_GPIO_INITIAL_LEVEL[16] PROGMEM = {{{initial_levels_s}}}" ) ) From 87f40cf24a866096396da2b967072b0e86a1ded3 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 3 Sep 2025 22:56:15 -0500 Subject: [PATCH 4/4] cleanup --- esphome/components/esp8266/core.cpp | 4 ++-- esphome/components/esp8266/core.h | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/esphome/components/esp8266/core.cpp b/esphome/components/esp8266/core.cpp index 07659b34c8..200ca567c2 100644 --- a/esphome/components/esp8266/core.cpp +++ b/esphome/components/esp8266/core.cpp @@ -58,8 +58,8 @@ extern "C" void resetPins() { // NOLINT #ifdef USE_ESP8266_EARLY_PIN_INIT for (int i = 0; i < 16; i++) { - uint8_t mode = pgm_read_byte(&ESPHOME_ESP8266_GPIO_INITIAL_MODE[i]); - uint8_t level = pgm_read_byte(&ESPHOME_ESP8266_GPIO_INITIAL_LEVEL[i]); + uint8_t mode = progmem_read_byte(&ESPHOME_ESP8266_GPIO_INITIAL_MODE[i]); + uint8_t level = progmem_read_byte(&ESPHOME_ESP8266_GPIO_INITIAL_LEVEL[i]); if (mode != 255) pinMode(i, mode); // NOLINT if (level != 255) diff --git a/esphome/components/esp8266/core.h b/esphome/components/esp8266/core.h index 6daf0fd110..8c9ffd40a4 100644 --- a/esphome/components/esp8266/core.h +++ b/esphome/components/esp8266/core.h @@ -3,7 +3,6 @@ #ifdef USE_ESP8266 #include -#include extern const uint8_t ESPHOME_ESP8266_GPIO_INITIAL_MODE[16] PROGMEM; extern const uint8_t ESPHOME_ESP8266_GPIO_INITIAL_LEVEL[16] PROGMEM;