Fix ISR safety: ESP32 without fast select needs xPortInIsrContext detection

This commit is contained in:
J. Nick Koston
2026-04-04 11:30:45 -10:00
parent aa0e56bfde
commit 63b8275e23
2 changed files with 17 additions and 5 deletions
+4 -2
View File
@@ -12,11 +12,13 @@
namespace esphome {
// === ESP32 — IRAM_ATTR entry points (fast-select only) ===
#if defined(USE_ESP32) && defined(USE_LWIP_FAST_SELECT)
// === ESP32 — IRAM_ATTR entry points ===
#ifdef USE_ESP32
#ifdef USE_LWIP_FAST_SELECT
void IRAM_ATTR wake_loop_isrsafe(int *px_higher_priority_task_woken) {
wake_loop_isrsafe_inline_(px_higher_priority_task_woken);
}
#endif
void IRAM_ATTR wake_loop_any_context() { wake_loop_any_context_inline_(); }
#endif
+13 -3
View File
@@ -56,10 +56,21 @@ void wake_loop_any_context();
inline void wake_loop_threadsafe() { esphome_lwip_wake_main_loop(); }
#else
inline void wake_loop_any_context() {
if (g_main_task_handle != nullptr)
/// Inline impl — ISR callers inline this into IRAM. Uses xPortInIsrContext() to pick safe API.
inline void ESPHOME_ALWAYS_INLINE wake_loop_any_context_inline_() {
if (g_main_task_handle == nullptr)
return;
if (xPortInIsrContext()) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
vTaskNotifyGiveFromISR(g_main_task_handle, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
} else {
xTaskNotifyGive(g_main_task_handle);
}
}
/// IRAM_ATTR entry point — defined in wake.cpp.
void wake_loop_any_context();
inline void wake_loop_threadsafe() {
if (g_main_task_handle != nullptr)
xTaskNotifyGive(g_main_task_handle);
@@ -69,7 +80,6 @@ inline void wake_loop_threadsafe() {
namespace internal {
inline void wakeable_delay(uint32_t ms) {
#ifndef USE_LWIP_FAST_SELECT
// Cache main task handle on first call
if (g_main_task_handle == nullptr)
g_main_task_handle = xTaskGetCurrentTaskHandle();
#endif