[esp32] Add ISR safety check for constrained env logging

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).
This commit is contained in:
J. Nick Koston
2026-03-13 18:05:07 -10:00
parent 98f0e53053
commit 623f7249b8
+19 -6
View File
@@ -140,12 +140,25 @@ extern "C" {
void IRAM_ATTR esp_log_format(esp_log_msg_t *message) {
extern vprintf_like_t esp_log_vprint_func;
extern int vprintf(const char *, __gnuc_va_list); // NOLINT
if (esp_log_vprint_func == &vprintf || message->config.opts.constrained_env) [[unlikely]] {
// Early boot or constrained env (PHY init, ISR): can't use the ESPHome
// hook (fwrite locks crash during PHY init on USB JTAG devices).
// Format to stack buffer with vsnprintf + esp_rom_printf (both safe
// without stdio locks). vsnprintf writes to a buffer (no stdio init
// needed), esp_rom_printf is ROM-resident.
if (message->config.opts.constrained_env) [[unlikely]] {
// Constrained env: constrained_env combines three conditions —
// scheduler not running, in ISR, or cache disabled. Only the first
// is safe for flash access. Check ISR context explicitly to decide.
if (xPortInIsrContext()) {
// In ISR: flash may be inaccessible. Output tag only via ROM printf.
// This matches V1 behavior where ISR logging was best-effort.
static DRAM_ATTR const char isr_fmt[] = "[%s] (ISR log)\n";
esp_rom_printf(isr_fmt, message->tag ? message->tag : "idf");
} else {
// Scheduler not running or PHY init: flash is accessible.
// Use stack buffer formatting (can't use ESPHome hook — fwrite
// locks crash during PHY init on USB JTAG devices).
esp_log_format_early_(message);
}
return;
}
if (esp_log_vprint_func == &vprintf) [[unlikely]] {
// Early boot: hook not installed yet. Format with ESPHome style.
esp_log_format_early_(message);
return;
}