Merge remote-tracking branch 'origin/esp8266-wake-loop-any-context' into integration

This commit is contained in:
J. Nick Koston
2026-02-28 15:36:17 -10:00
4 changed files with 16 additions and 8 deletions
@@ -41,7 +41,7 @@ void socket_delay(uint32_t ms) {
esp_delay(ms, []() { return !s_socket_woke; });
}
void socket_wake() {
void IRAM_ATTR socket_wake() {
s_socket_woke = true;
esp_schedule();
}
+2 -1
View File
@@ -126,7 +126,8 @@ size_t format_sockaddr_to(const struct sockaddr *addr_ptr, socklen_t len, std::s
/// On ESP8266, lwip callbacks set a flag and call esp_schedule() to wake the delay.
void socket_delay(uint32_t ms);
/// Called by lwip callbacks to signal socket activity and wake delay.
/// Signal socket/IO activity and wake the main loop from esp_delay() early.
/// ISR-safe: uses IRAM_ATTR internally and only sets a volatile flag + esp_schedule().
void socket_wake();
#endif
+7
View File
@@ -32,6 +32,9 @@
#include <lwip/sockets.h>
#endif
#endif
#if defined(USE_ESP8266) && defined(USE_SOCKET_IMPL_LWIP_TCP)
#include "esphome/components/socket/socket.h"
#endif
#endif // USE_SOCKET_SELECT_SUPPORT
#ifdef USE_BINARY_SENSOR
@@ -630,6 +633,10 @@ class Application {
/// Wake the main event loop from any context (ISR, thread, or main loop).
/// Detects the calling context and uses the appropriate FreeRTOS API.
static void IRAM_ATTR wake_loop_any_context() { esphome_lwip_wake_main_loop_any_context(); }
#elif defined(USE_ESP8266) && defined(USE_SOCKET_IMPL_LWIP_TCP)
/// Wake the main event loop from any context (ISR, thread, or main loop).
/// On ESP8266: sets the socket wake flag and calls esp_schedule() to exit esp_delay() early.
static void IRAM_ATTR wake_loop_any_context() { socket::socket_wake(); }
#endif
#endif
+6 -6
View File
@@ -336,12 +336,12 @@ void IRAM_ATTR HOT Component::enable_loop_soon_any_context() {
// 8. Race condition with main loop is handled by clearing flag before processing
this->pending_enable_loop_ = true;
App.has_pending_enable_loop_requests_ = true;
#ifdef USE_LWIP_FAST_SELECT
// Wake the main loop if sleeping in ulTaskNotifyTake(). Without this,
// the main loop would not wake until the select timeout expires (~16ms).
// Uses platform-specific context detection to choose the correct notify
// API (task vs ISR), e.g. xPortInIsrContext() on ESP32 or IPSR register
// on LibreTiny — safe from any calling context.
#if defined(USE_LWIP_FAST_SELECT) || (defined(USE_ESP8266) && defined(USE_SOCKET_IMPL_LWIP_TCP))
// Wake the main loop from sleep. Without this, the main loop would not
// wake until the select/delay timeout expires (~16ms).
// ESP32/LibreTiny: uses platform-specific context detection (xPortInIsrContext
// or IPSR register) to choose the correct FreeRTOS notify API.
// ESP8266: sets socket wake flag and calls esp_schedule() to exit esp_delay() early.
Application::wake_loop_any_context();
#endif
}