rust-embedded/rust-raspberrypi-OS-tutorials · error
Error handling IRQ
Error message
Error handling IRQ
What it means
In the BCM local interrupt controller, a registered handler's handle() returning Err triggers .expect("Error handling IRQ"), panicking. The library surfaces handler failures as fatal because the local IRQ cannot be considered serviced and the system state is undefined.
Source
Thrown at 20_timer_callbacks/kernel/src/bsp/device_driver/bcm/bcm2xxx_interrupt_controller/local_ic.rs:153
let enable_bit: u32 = 1 << (irq.get());
// 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.
regs.CORE0_TIMER_INTERRUPT_CONTROL.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!(" Local 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
- Read the specific Err from the failing handler's handle() and fix the underlying peripheral interaction (clear/ack the correct register).
- Ensure per-core device initialization completes before enabling the core's local IRQs.
- Make the handler robust to spurious firings (acknowledge and return Ok instead of Err).
- Check for races: disable the IRQ while reconfiguring the device it belongs to.
Example fix
// before
fn handle(&self) -> Result<(), &'static str> {
Err("no pending source") // -> expect("Error handling IRQ") panic
}
// after
fn handle(&self) -> Result<(), &'static str> {
if self.pending() { self.clear_pending(); }
Ok(())
} Defensive patterns
Strategy: validation
Validate before calling
// Ensure per-core device init completed before enabling its local IRQ:
if !local_timer_initialized_on(core_id) { panic!("init local timer before enabling its IRQ"); } Prevention
- Initialize per-core devices before enabling their local IRQs.
- Acknowledge pending sources even on spurious firings to keep handle() returning Ok.
- Disable IRQs while reconfiguring the device they belong to.
- Match handler logic to the exact BCM chip revision in use.
When it happens
Trigger: The handler registered for a pending local IRQ (e.g. local timer) returns Err from handle() — internal state checks fail, the peripheral's pending bit cannot be cleared, or the handler's expected device state is absent when the IRQ arrives.
Common situations: Local timer handler running before the timer was initialized on that core, status-register bit layouts differing between BCM2837 and BCM2711, shared IRQs where the handler finds no source to service, and re-entrant IRQ handling corrupting handler state.
Related errors
- No handler registered for IRQ {}
- No handler registered for IRQ {}
- Error handling 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/078cfc91881550bc.
Report an issue: GitHub.