rust-embedded/rust-raspberrypi-OS-tutorials · error
Error handling IRQ
Error message
Error handling IRQ
What it means
In the BCM peripheral interrupt controller, when a registered handler's handle() returns Err, .expect("Error handling IRQ") panics. The library escalates handler-internal failures because the interrupt cannot be confirmed serviced and the peripheral may remain in a pending state.
Source
Thrown at 20_timer_callbacks/kernel/src/bsp/device_driver/bcm/bcm2xxx_interrupt_controller/peripheral_ic.rs:158
let enable_bit: u32 = 1 << (irq.get() % 32);
// Writing a 1 to a bit will set the corresponding IRQ enable bit. All other IRQ enable
// bits are unaffected. So we don't need read and OR'ing here.
enable_reg.set(enable_bit);
});
}
fn handle_pending_irqs<'irq_context>(
&'irq_context self,
_ic: &exception::asynchronous::IRQContext<'irq_context>,
) {
self.handler_table.read(|table| {
for irq_number in self.pending_irqs() {
match table[irq_number] {
None => panic!("No handler registered for IRQ {}", irq_number),
Some(descriptor) => {
// Call the IRQ handler. Panics on failure.
descriptor.handler().handle().expect("Error handling IRQ");
}
}
}
})
}
fn print_handler(&self) {
use crate::info;
info!(" Peripheral handler:");
self.handler_table.read(|table| {
for (i, opt) in table.iter().enumerate() {
if let Some(handler) = opt {
info!(" {: >3}. {}", i, handler.name());
}
}
});View on GitHub (pinned to 644474cc09)
Solutions
- Trace the concrete Err returned by the failing handler and fix the device servicing logic (correct status/clear registers).
- Disable the IRQ while reconfiguring its device, then re-enable after the handler's invariants hold.
- Make handlers tolerant of spurious or shared-IRQ firings by acknowledging and returning Ok.
- Ensure the device behind the handler is fully initialized before its IRQ is unmasked.
Example fix
// before
fn handle(&self) -> Result<(), &'static str> {
Err("M1 bit not set") // -> expect("Error handling IRQ") panic
}
// after
fn handle(&self) -> Result<(), &'static str> {
self.timer.clear_matched();
Ok(())
} Defensive patterns
Strategy: validation
Validate before calling
// Verify the device can service its IRQ before enabling it:
if !gpio.event_config_valid(pin) { panic!("configure GPIO event before enabling its IRQ"); } Prevention
- Write handlers that acknowledge unconditionally so spurious/shared IRQs return Ok.
- Freeze device configuration before enabling its IRQ; reconfigure only with the IRQ masked.
- Keep handler state private and immutable after init to avoid races.
- Test each handler's Err paths and eliminate them by construction.
When it happens
Trigger: The handler registered for a pending peripheral IRQ returns Err from handle() — its device-specific servicing logic fails (status bit not set as expected, clear operation rejected, internal invariant broken) at the moment the IRQ fires.
Common situations: System-timer handler invoked with a mismatched compare register configuration, GPIO handler triggered by a pin whose event configuration was changed after enabling the IRQ, drivers sharing IRQs with incompatible handlers, or handler state invalidated by re-initialization while the IRQ stays enabled.
Related errors
- No handler registered for IRQ {}
- Error handling IRQ
- No handler registered for IRQ {}
- No handler registered for IRQ {}
- Error handling IRQ
AI-assisted analysis of rust-embedded/rust-raspberrypi-OS-tutorials@644474cc09 (2026-09-06).
Data as JSON: /api/errors/1237c2396f52c807.
Report an issue: GitHub.