Home IO Control
ESPHome add-on for IO-Homecontrol devices
Toggle main menu visibility
Loading...
Searching...
No Matches
radio_poll.h
Go to the documentation of this file.
1
#pragma once
2
3
/// @file radio_poll.h
4
/// @brief Preemption-safe "poll a condition until it holds or a deadline passes" helper.
5
/// @ingroup hioc_radio
6
///
7
/// Every blocking radio wait that samples a device and then compares a clock has the same hazard:
8
/// if the task is descheduled between the two reads for longer than the timeout (a Wi-Fi scan, a
9
/// flash write), the clock says "expired" while the device sample is already stale. Deciding on
10
/// that stale sample declares a ready device dead. poll_until() fixes the order once, for every
11
/// wait that must not misjudge a device on the strength of an old sample.
12
13
#include "esphome/core/hal.h"
14
#include "esphome/core/application.h"
15
16
#include <cstdint>
17
18
namespace
esphome
{
19
namespace
home_io_control
{
20
21
/// Outcome of @ref poll_until.
22
struct
PollResult
{
23
bool
ready
{
false
};
///< The condition held on the deciding sample.
24
uint32_t
elapsed_ms
{0};
///< Time from the first sample to the last clock read before the deciding one.
25
};
26
27
/// @brief Poll `ready()` until it is true or `timeout_ms` has passed, feeding the watchdog between samples.
28
///
29
/// The decision to give up is always taken on a sample read *after* the deadline was seen to pass,
30
/// so a task preempted for longer than the timeout can only make the wait longer; it can never make
31
/// a condition that became true look false. A caller can tell such an overrun from a clean success
32
/// by `ready && elapsed_ms > timeout_ms`.
33
///
34
/// The start time is the only clock read before the first sample, and each loop iteration reads the
35
/// clock once, so an already-satisfied condition costs exactly one `millis()` call (this runs before
36
/// every SPI transaction on the software-PHY chips, and host tests on the counting clock rely on it).
37
/// @tparam Ready Callable returning bool; true means the condition holds.
38
/// @param ready Condition to sample.
39
/// @param timeout_ms Window in milliseconds; the wait gives up once more than this has elapsed.
40
template
<
typename
Ready>
PollResult
poll_until
(Ready ready, uint32_t timeout_ms) {
41
uint32_t
const
start = millis();
42
if
(ready())
43
return
{
true
, 0};
44
while
(
true
) {
45
uint32_t
const
elapsed = millis() - start;
46
if
(elapsed > timeout_ms) {
47
bool
const
last = ready();
// the deciding sample, taken after the deadline
48
return
{last, elapsed};
49
}
50
if
(ready())
51
return
{
true
, elapsed};
52
App.feed_wdt();
53
}
54
}
55
56
}
// namespace home_io_control
57
}
// namespace esphome
esphome::home_io_control
Definition
device_registry.cpp:16
esphome::home_io_control::poll_until
PollResult poll_until(Ready ready, uint32_t timeout_ms)
Poll ready() until it is true or timeout_ms has passed, feeding the watchdog between samples.
Definition
radio_poll.h:40
esphome
Definition
device_registry.cpp:15
esphome::home_io_control::PollResult
Outcome of poll_until.
Definition
radio_poll.h:22
esphome::home_io_control::PollResult::elapsed_ms
uint32_t elapsed_ms
Time from the first sample to the last clock read before the deciding one.
Definition
radio_poll.h:24
esphome::home_io_control::PollResult::ready
bool ready
The condition held on the deciding sample.
Definition
radio_poll.h:23
components
home_io_control
radio_poll.h
Generated by
1.18.0