Put IRAM_ATTR back on esp_log_format (tiny ~43 byte dispatch function)
to match esp_log_va's IRAM placement and avoid cache miss. Leave the
512-byte formatting function in flash — it's cold on 99.9% of builds
(only runs during early boot and at DEBUG framework log level).
The ISR with cache disabled case can't be handled without
esp_rom_vprintf — the caller's format string and tag are also in
flash, so even esp_rom_printf would crash. This is the same
limitation V1 had. Document it and keep the simpler code.
constrained_env combines three conditions: scheduler not running,
in ISR, or cache disabled. Only the first is safe for flash access.
Check xPortInIsrContext() (IRAM-resident) explicitly:
- In ISR: output tag only via esp_rom_printf (ROM). Flash may be
inaccessible. This matches V1 behavior where ISR logging was
best-effort.
- Not in ISR (scheduler not running, PHY init): call flash-resident
esp_log_format_early_ which formats the full message.
This ensures the override is safe for all constrained env cases
without pulling in esp_rom_vprintf (1.2KB IRAM).
- Route constrained env (PHY init, efuse reads) through the early
boot path which uses vsnprintf + esp_rom_printf. This avoids both
the fwrite lock crash on USB JTAG devices and pulling in
esp_rom_vprintf (1.2KB IRAM).
- Call esp_log_vprint_func directly on the normal path instead of
going through the esp_log_vprintf inline (which would reference
esp_rom_vprintf for the constrained env dispatch).
- Remove IRAM_ATTR from esp_log_format_early_ since it's only called
when flash is accessible (early boot and constrained env with cache
enabled like PHY init and efuse reads).
ESP-IDF places log_format_text.c in IRAM/DRAM via linker fragment
(noflash) when CONFIG_LOG_IN_IRAM=y. Our override is in a different
compilation unit so string literals would default to flash. In
constrained environments where flash cache is disabled, reading
flash-resident format strings would fault.
Move all format string constants to DRAM_ATTR to match ESP-IDF's
own behavior.
Switch from ESP-IDF Log V1 to V2, which centralizes log formatting
inside esp_log() instead of expanding esp_log_timestamp(), color codes,
and LOG_FORMAT() at every ESP_LOGx macro call site.
This saves ~9KB of flash by eliminating ~500 per-site macro expansions
in ESP-IDF library code (gpio, ethernet, mdns, uart, wifi, etc.).
Override esp_log_format() to skip ESP-IDF's own formatting after the
ESPHome logger hook is installed, since ESPHome does its own formatting.
For early boot and constrained environments (ISR, cache disabled),
format messages in ESPHome style with colors using a stack buffer.