diff --git a/esphome/core/component.cpp b/esphome/core/component.cpp index 00a36fce3d..8f9d6e0165 100644 --- a/esphome/core/component.cpp +++ b/esphome/core/component.cpp @@ -280,8 +280,8 @@ bool Component::should_warn_of_blocking(uint32_t blocking_time) { // Set new threshold: blocking_time + increment, converted back to centiseconds uint32_t new_threshold_ms = blocking_time + WARN_IF_BLOCKING_INCREMENT_MS; uint32_t new_cs = new_threshold_ms / 10U; - // Saturate at uint8_t max (255 = 2550ms) - this->warn_if_blocking_over_ = static_cast(new_cs > 255U ? 255U : new_cs); + // Saturate at 7-bit max (127 = 1270ms) + this->warn_if_blocking_over_ = static_cast(new_cs > 127U ? 127U : new_cs); return true; } return false; @@ -543,6 +543,6 @@ void clear_setup_priority_overrides() { #endif // Weak default for component_source_lookup - overridden by generated code -__attribute__((weak)) const LogString *component_source_lookup(uint8_t) { return LOG_STR(""); } +__attribute__((weak)) const LogString *component_source_lookup(uint16_t) { return LOG_STR(""); } } // namespace esphome diff --git a/esphome/core/component.h b/esphome/core/component.h index c390a205f0..fd57478291 100644 --- a/esphome/core/component.h +++ b/esphome/core/component.h @@ -90,7 +90,7 @@ inline constexpr uint8_t WARN_IF_BLOCKING_OVER_CS = 5U; // 50ms in centiseconds /// Lookup component source name by index (1-based). Generated by Python codegen. /// Weak default returns "" so builds without codegen still link. -const LogString *component_source_lookup(uint8_t index); +const LogString *component_source_lookup(uint16_t index); class Component { public: @@ -300,7 +300,7 @@ class Component { * This is set by the ESPHome core during setup, and should not be called manually. * @param index 1-based index into the component source lookup table (0 = not set) */ - void set_component_source_(uint8_t index) { this->component_source_index_ = index; } + void set_component_source_(uint16_t index) { this->component_source_index_ = index; } virtual void call_setup(); void call_dump_config_(); @@ -519,8 +519,9 @@ class Component { void status_clear_error_slow_path_(); // Ordered for optimal packing on 32-bit systems (8 bytes total with vtable) - uint8_t component_source_index_{0}; ///< Index into component source PROGMEM lookup table (0 = not set) - uint8_t warn_if_blocking_over_{WARN_IF_BLOCKING_OVER_CS}; ///< Warn threshold in centiseconds (max 2550ms) + // Bitfield packs into 16 bits: 9-bit source index (0-511) + 7-bit blocking threshold (0-127 centiseconds) + uint16_t component_source_index_ : 9 {0}; ///< Index into component source PROGMEM lookup table (0 = not set) + uint16_t warn_if_blocking_over_ : 7 {WARN_IF_BLOCKING_OVER_CS}; ///< Warn threshold in centiseconds (max 1270ms) /// State of this component - each bit has a purpose: /// Bits 0-2: Component state (0x00=CONSTRUCTION, 0x01=SETUP, 0x02=LOOP, 0x03=FAILED, 0x04=LOOP_DONE) /// Bit 3: STATUS_LED_WARNING diff --git a/esphome/cpp_helpers.py b/esphome/cpp_helpers.py index e7ff2965c8..66fe24b470 100644 --- a/esphome/cpp_helpers.py +++ b/esphome/cpp_helpers.py @@ -26,8 +26,8 @@ _LOGGER = logging.getLogger(__name__) _COMPONENT_SOURCE_DOMAIN = "component_source_pool" -# Maximum unique component source names (8-bit index, 0 = not set) -_MAX_COMPONENT_SOURCES = 0xFF # 255 +# Maximum unique component source names (9-bit index, 0 = not set) +_MAX_COMPONENT_SOURCES = 0x1FF # 511 @dataclass @@ -110,7 +110,7 @@ def _generate_source_table_code( entries = ", ".join(var_names) lines.append(f"static const char *const {table_var}[] PROGMEM = {{{entries}}};") - lines.append(f"const LogString *{lookup_fn}(uint8_t index) {{") + lines.append(f"const LogString *{lookup_fn}(uint16_t index) {{") lines.append(f' if (index == 0 || index > {count}) return LOG_STR("");') lines.append(" return reinterpret_cast(") lines.append(f" progmem_read_ptr(&{table_var}[index - 1]));") diff --git a/tests/unit_tests/test_cpp_helpers.py b/tests/unit_tests/test_cpp_helpers.py index 52424a7cb2..63cb5be6d0 100644 --- a/tests/unit_tests/test_cpp_helpers.py +++ b/tests/unit_tests/test_cpp_helpers.py @@ -137,7 +137,7 @@ def test_register_component_source_overflow_warns( ) -> None: # Pre-fill pool to max pool = ComponentSourcePool( - sources={f"comp_{i}": i + 1 for i in range(0xFF)}, + sources={f"comp_{i}": i + 1 for i in range(0x1FF)}, table_registered=True, ) monkeypatch.setattr(ch, "CORE", Mock(data={ch._COMPONENT_SOURCE_DOMAIN: pool}))