From 670a23b4c1c7823dd80436cfeec612f43eacb7c9 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 4 Apr 2026 12:59:34 -1000 Subject: [PATCH] Fix LibreTiny ISR safety: use vTaskNotifyGiveFromISR in wake_loop_any_context, update stale comment --- esphome/core/lwip_fast_select.c | 10 +++++----- esphome/core/wake.h | 11 +++++++++-- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/esphome/core/lwip_fast_select.c b/esphome/core/lwip_fast_select.c index 82b68aa738b..bb3acbafcb1 100644 --- a/esphome/core/lwip_fast_select.c +++ b/esphome/core/lwip_fast_select.c @@ -63,12 +63,12 @@ // // Shared state and safety rationale: // -// esphome_main_task_handle (TaskHandle_t, 4 bytes): -// Written once by main loop in init(). Read by TCP/IP thread (in callback) -// and background tasks (in wake). -// Safe: write-once-then-read pattern. Socket hooks may run before init(), +// esphome_main_task_handle (TaskHandle_t, 4 bytes, defined in main_task.c): +// Written once by main loop in Application::setup(). Read by TCP/IP thread +// (in callback) and background tasks (in wake). +// Safe: write-once-then-read pattern. Socket hooks may run before setup(), // but the NULL check on esphome_main_task_handle in the callback provides correct -// degraded behavior — notifications are simply skipped until init() completes. +// degraded behavior — notifications are simply skipped until setup() completes. // // s_original_callback (netconn_callback, 4-byte function pointer): // Written by main loop in hook_socket() (only when NULL — set once). diff --git a/esphome/core/wake.h b/esphome/core/wake.h index 7f4fcd60da7..bed1d64561d 100644 --- a/esphome/core/wake.h +++ b/esphome/core/wake.h @@ -34,8 +34,15 @@ void wake_loop_isrsafe(int *px_higher_priority_task_woken); /// IRAM_ATTR entry point — defined in wake.cpp. void wake_loop_any_context(); #else -/// LibreTiny: no working IRAM_ATTR, no ISR callers. -inline void wake_loop_any_context() { esphome_main_task_notify(); } +/// LibreTiny: GPIO ISRs are real hardware interrupts, so use ISR-safe API. +/// vTaskNotifyGiveFromISR is safe from both ISR and task context on ARM Cortex-M. +inline void wake_loop_any_context() { + if (esphome_main_task_handle != NULL) { + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + vTaskNotifyGiveFromISR(esphome_main_task_handle, &xHigherPriorityTaskWoken); + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + } +} #endif inline void wake_loop_threadsafe() { esphome_main_task_notify(); }