Expand description
Bounded busy-waits for blocking driver paths.
A blocking transfer that polls a status flag spins forever if the flag never
comes: a target holding SCL low, a peripheral whose kernel clock was gated
behind the driver’s back, a DMA channel that never reaches idle. embassy-stm32
bounds those loops with a Timeout that reads embassy-time when it can and
never expires when it cannot. Consortium’s drivers also spin in Drop guards
and before any time driver is running, so this Timeout counts polls instead
of reading a clock: it works everywhere, and it always expires.
The cost is that a poll budget is not a duration. One poll is one status read
plus loop overhead, so the wall-clock bound scales inversely with the core
clock; Timeout::DEFAULT is generous enough to cover a clock-stretched I2C
byte at 10 kHz on a 1 GHz core and still bounded on a slow one.
use consortium_hal::timeout::Timeout;
let mut ready = 3;
let mut wait = Timeout::polls(10).start();
let result = loop {
ready -= 1;
if ready == 0 {
break Ok(());
}
if let Err(e) = wait.tick() {
break Err(e);
}
};
assert_eq!(result, Ok(()));Structs§
- Deadline
- One wait in progress; see
Timeout::start. - Timed
Out - A bounded wait ran out of polls. Drivers map it to their own
Error::Timeout. - Timeout
- The poll budget a blocking wait may spend before giving up.