embassy-rs/embassy · error
Waker not present for GPIO pin
Error message
Waker not present for GPIO pin {}, port {} What it means
Panic in InputFuture::poll: after verifying the port's waker slot exists, the code indexes into it with the pin number and finds no waker registered for that specific pin. The per-pin waker is what the GPIO interrupt handler wakes when the configured edge occurs; without it, awaiting the pin's edge would hang forever. This indicates the InputFuture is polling a pin whose interrupt configuration was never registered — typically a pin used before its interrupt was enabled, or a stale future for a pin that was reconfigured or torn down.
Solutions
- Enable/configure the pin interrupt for this specific pin before awaiting edges on it
- Keep the Input (and its future) alive only while its interrupt configuration is active; re-create the future after reconfiguring the pin
- Don't tear down or re-register the pin's interrupt config while an InputFuture is polling it
- Trace with the pin and port numbers in the message which pin was misconfigured and fix its setup call
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at embassy-imxrt/src/gpio.rs:456 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/fcf195d256b29d90.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-imxrt/src/gpio.rs:456
impl Future for InputFuture<'_> {
type Output = ();
fn poll(self: FuturePin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
// We need to register/re-register the waker for each poll because any
// calls to wake will deregister the waker.
if self.pin.port() >= GPIO_WAKERS.len() {
panic!("Invalid GPIO port index {}", self.pin.port());
}
let port_waker = GPIO_WAKERS[self.pin.port()];
if port_waker.is_none() {
panic!("Waker not present for GPIO port {}", self.pin.port());
}
let waker = port_waker.unwrap().get_waker(self.pin.pin());
if waker.is_none() {
panic!(
"Waker not present for GPIO pin {}, port {}",
self.pin.pin(),
self.pin.port()
);
}
waker.unwrap().register(cx.waker());
// Double check that the pin interrut has been disabled by IRQ handler
if self.pin.block().intena(self.pin.port()).read().bits() & (1 << self.pin.pin()) == 0 {
Poll::Ready(())
} else {
Poll::Pending
}
}
}
/// Output pin
/// Cannot be set as an input and cannot read its own pin state!View on GitHub (pinned to 463a07b963)