Interrupts are vital for real-time responsiveness in Linux kernel modules. Whether you’re writing drivers for GPIOs, network interfaces, or custom hardware, implementing IRQ (Interrupt Request) handlers allows the kernel to respond to hardware events asynchronously—without polling.
This tutorial covers:
- What IRQs are
- How to register an interrupt handler
- A sample Linux kernel module
- Proper cleanup and best practices
📌 What is an IRQ?
IRQ stands for Interrupt Request. When a hardware device needs the CPU’s attention, it sends an IRQ signal. The kernel then interrupts the current process to run the associated handler.
🛠️ Step-by-Step: Implementing an IRQ Handler in a Kernel Module
✅ 1. Include Required Headers
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
✅ 2. Define Device IRQ and Handler
Choose an IRQ number (you may obtain it via /proc/interrupts
or platform_get_irq()
for platform devices).
#define MY_IRQ_LINE 19 // Replace with actual IRQ number
static irqreturn_t my_irq_handler(int irq, void *dev_id) {
printk(KERN_INFO "IRQ %d triggered!\n", irq);
return IRQ_HANDLED;
}
✅ 3. Request IRQ in init
Function
static int __init irq_module_init(void) {
int result;
result = request_irq(MY_IRQ_LINE, my_irq_handler, IRQF_SHARED, "my_irq_handler", (void *)(my_irq_handler));
if (result) {
printk(KERN_ERR "Failed to request IRQ %d\n", MY_IRQ_LINE);
return result;
}
printk(KERN_INFO "IRQ handler registered successfully\n");
return 0;
}
✅ 4. Free IRQ in exit
Function
static void __exit irq_module_exit(void) {
free_irq(MY_IRQ_LINE, (void *)(my_irq_handler));
printk(KERN_INFO "IRQ handler unregistered\n");
}
✅ 5. Declare Module Init/Exit
module_init(irq_module_init);
module_exit(irq_module_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple IRQ handler example");
🔎 Testing the Module
Compile and insert your module:
make
sudo insmod irq_module.ko
dmesg | tail
Trigger the interrupt (depends on your hardware) and observe:
cat /proc/interrupts
Check for your IRQ number and count increment.
⚠️ Important Notes
Tip | Explanation |
---|---|
Use IRQF_SHARED | If IRQ is shared among multiple devices |
Always free_irq() | Prevent memory leaks or undefined behavior on module unload |
Avoid heavy processing in handler | Defer using tasklets or workqueues if needed |
Implementing an interrupt handler in a Linux kernel driver is a core skill for low-level systems programmers. By correctly registering and cleaning up IRQs, you ensure your driver responds quickly to hardware events—without hogging CPU cycles.
With this knowledge, you can now:
- Handle GPIO interrupts
- Build event-driven drivers
- Expand into threaded IRQs or real-time Linux work
Have you implemented IRQ handlers in your drivers?
Need help debugging spurious interrupts or shared IRQ conflicts? Drop your thoughts and questions in the comments below! 🧑💻👇