mirror of
https://github.com/esphome/esphome.git
synced 2026-07-10 17:05:36 +00:00
[core] Add ESP8266 support to wake_loop_any_context()
Wire Application::wake_loop_any_context() to socket::socket_wake() on ESP8266. This allows any component calling wake_loop_any_context() from an ISR or callback to immediately wake the main loop from esp_delay() sleep, instead of waiting up to 16ms for the timeout. Changes: - Add IRAM_ATTR to socket_wake() so it's safe to call from ISR context - Add ESP8266 wake_loop_any_context() backed by socket::socket_wake() - Extend enable_loop_soon_any_context() to wake the loop on ESP8266
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -33,6 +33,9 @@
|
||||
#endif
|
||||
#endif
|
||||
#endif // USE_SOCKET_SELECT_SUPPORT
|
||||
#if defined(USE_ESP8266) && defined(USE_SOCKET_IMPL_LWIP_TCP)
|
||||
#include "esphome/components/socket/socket.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_BINARY_SENSOR
|
||||
#include "esphome/components/binary_sensor/binary_sensor.h"
|
||||
@@ -518,6 +521,12 @@ class Application {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if 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
|
||||
|
||||
protected:
|
||||
friend Component;
|
||||
friend class socket::Socket;
|
||||
|
||||
@@ -323,10 +323,11 @@ 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;
|
||||
#if defined(USE_LWIP_FAST_SELECT) && defined(USE_ESP32)
|
||||
// Wake the main loop if sleeping in ulTaskNotifyTake(). Without this,
|
||||
// the main loop would not wake until the select timeout expires (~16ms).
|
||||
// Uses xPortInIsrContext() to choose the correct FreeRTOS notify API.
|
||||
#if (defined(USE_LWIP_FAST_SELECT) && defined(USE_ESP32)) || (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: uses xPortInIsrContext() 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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user