When a repeated enum field has a constant size per element (max < 128),
emit size * constant instead of iterating. This fixes unused variable
warnings from clang-tidy and generates more efficient code.
The protobuf code generator already parses all enum definitions and
knows every enum's maximum value. Use this to automatically apply the
max_value < 128 optimization to all enum fields, eliminating the need
for manual annotation.
Since every enum in api.proto has max < 128, all 58 enum field size
calculations now use constant arithmetic instead of calling varint
size functions.
Builds on #15424 which introduced the max_value optimization.
Reduce preferences normal region from 96 to 78 words (words 32-109)
to formally reserve words 110-127 for the crash handler backtrace.
Preferences that don't fit in RTC fall back to flash storage, so
this has no functional impact for typical configurations.
- Add IRAM_ATTR to is_code_addr/recover_code_addr as safety net
in case the compiler doesn't inline them
- Restore EXCVADDR logging for exception resets (faulting address
is the key diagnostic for LoadProhibit/StoreProhibit)
- Add comment noting Xtensa stack pointer alignment assumption
- Match Arduino core's declaration of _irom0_text_start/_end as
void functions (mmu_iram.h declares them this way)
- Use C-style casts with NOLINT for int-to-ptr conversions in
custom_crash_callback (clang-tidy performance-no-int-to-ptr)
The ESPHome CLI already decodes addresses inline (shown as
WARNING Decoded lines). The hint was redundant and cost ~100
bytes of flash plus 220 bytes of stack for the format buffer.
The LX106 (ESP8266) has no MMU, TLB, PIF, or privilege levels, so
exception causes 1, 5, 7, 8, 12-18, and 24-26 can never occur.
Remove them and shorten remaining cause names. Also drop Syscall,
Alloca, PCValue, Privileged which are unreachable on this core.
GCC's ROM divide routine triggers IllegalInstruction (exccause=0) at
ROM addresses 0x4000dce5/0x4000dd3d instead of IntegerDivideByZero
(exccause=6). Patch exccause to match the Arduino core's postmortem
handler behavior.
WDT resets also populate exccause in rst_info (e.g. Level1Interrupt
for stack overflow soft WDT). Show the cause string for all crash
reasons, not just REASON_EXCEPTION_RST. Also simplify PC logging
to a single line for all crash types.
resetInfo is a global that persists until next reset — no need to
cache the crash validity in a separate bool. Check resetInfo.reason
directly in crash_handler_has_data() and crash_handler_log().
This eliminates the only RAM byte from the crash handler and removes
the now-empty crash_handler_read_and_clear() function and its call
from arch_init().
Remove EPC2/EPC3 (always 0 on LX106, no level 2/3 interrupts) and
DEPC (extremely rare double exception). Combine PC and EXCVADDR into
one log line for exception resets. Shrink hint buffer 256->220.
Saves ~36 bytes flash in crash_handler_log.
Switch statements generate CSWTCH jump tables in RAM on ESP8266.
PROGMEM_STRING_TABLE causes LoadStoreError from flash cache conflicts
in API subscribe paths. If-else with LOG_STR avoids both: strings
stay in flash via PSTR, and comparison branches don't need a data
table. Zero RAM overhead confirmed via nm.
Reading IROM addresses from IROM code causes LoadStoreError on ESP8266
due to the direct-mapped flash cache — the reading code and target
address can share a cache line, evicting the function mid-execution.
Remove is_return_addr() and rely on linker-symbol IROM bounds
(_irom0_text_start/_end) to eliminate false positives instead. This
is less precise but crash-safe.