ESPHome 2026.5.0-dev
Loading...
Searching...
No Matches
wake.h
Go to the documentation of this file.
1#pragma once
2
6
8#include "esphome/core/hal.h"
9
10#if defined(USE_ESP32) || defined(USE_LIBRETINY)
12#endif
13#ifdef USE_ESP8266
14#include <coredecls.h>
15#elif defined(USE_RP2040)
16#include <hardware/sync.h>
17#include <pico/time.h>
18#endif
19
20namespace esphome {
21
22// === Wake flag for ESP8266/RP2040 ===
23#if defined(USE_ESP8266) || defined(USE_RP2040)
24// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
25extern volatile bool g_main_loop_woke;
26#endif
27
28// === ESP32 / LibreTiny (FreeRTOS) ===
29#if defined(USE_ESP32) || defined(USE_LIBRETINY)
30
33__attribute__((always_inline)) inline void wake_main_task_any_context() {
34 if (in_isr_context()) {
35 BaseType_t px_higher_priority_task_woken = pdFALSE;
36 esphome_main_task_notify_from_isr(&px_higher_priority_task_woken);
37#ifdef portYIELD_FROM_ISR
38 portYIELD_FROM_ISR(px_higher_priority_task_woken);
39#else
40 // ARM9 FreeRTOS port (BK72xx) does not define portYIELD_FROM_ISR; the IRQ
41 // exit sequence performs the context switch if one was requested.
42 (void) px_higher_priority_task_woken;
43#endif
44 } else {
45 esphome_main_task_notify();
46 }
47}
48
50void wake_loop_isrsafe(BaseType_t *px_higher_priority_task_woken);
52
53inline void wake_loop_threadsafe() { esphome_main_task_notify(); }
54
55namespace internal {
56inline void wakeable_delay(uint32_t ms) {
57 if (ms == 0) {
58 yield();
59 return;
60 }
61 ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(ms));
62}
63} // namespace internal
64
65// === ESP8266 ===
66#elif defined(USE_ESP8266)
67
69inline void ESPHOME_ALWAYS_INLINE wake_loop_impl() {
70 g_main_loop_woke = true;
71 esp_schedule();
72}
73
76
78inline void wake_loop_threadsafe() { wake_loop_impl(); }
79
80namespace internal {
81inline void wakeable_delay(uint32_t ms) {
82 if (ms == 0) {
83 delay(0);
84 return;
85 }
86 if (g_main_loop_woke) {
87 g_main_loop_woke = false;
88 return;
89 }
90 esp_delay(ms, []() { return !g_main_loop_woke; });
91}
92} // namespace internal
93
94// === RP2040 ===
95#elif defined(USE_RP2040)
96
97inline void wake_loop_any_context() {
98 g_main_loop_woke = true;
99 __sev();
100}
101
103
105namespace internal {
106void wakeable_delay(uint32_t ms);
107} // namespace internal
108
109// === Host / Zephyr / other ===
110#else
111
112#ifdef USE_HOST
115#else
119inline void wake_loop_threadsafe() {}
120#endif
121
123
124namespace internal {
125inline void wakeable_delay(uint32_t ms) {
126 if (ms == 0) {
127 yield();
128 return;
129 }
130 delay(ms);
131}
132} // namespace internal
133
134#endif
135
136} // namespace esphome
struct @65::@66 __attribute__
Wake the main loop task from an ISR. ISR-safe.
Definition main_task.h:32
void wakeable_delay(uint32_t ms)
Definition wake.cpp:47
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
void wake_loop_threadsafe()
Non-ISR: always inline.
Definition wake.cpp:74
void ESPHOME_ALWAYS_INLINE wake_loop_impl()
Inline implementation — IRAM callers inline this directly.
Definition wake.h:69
volatile bool g_main_loop_woke
Definition wake.cpp:26
void HOT yield()
Definition core.cpp:25
void HOT delay(uint32_t ms)
Definition core.cpp:28
void IRAM_ATTR wake_loop_any_context()
IRAM_ATTR entry point for ISR callers — defined in wake.cpp.
Definition wake.cpp:20
void IRAM_ATTR wake_loop_isrsafe(BaseType_t *px_higher_priority_task_woken)
IRAM_ATTR entry points — defined in wake.cpp.
Definition wake.cpp:17
static void uint32_t