Implementation of Interrupt Handler (IRQ) in Linux kernel driver

Following driver implements, how we can allocate an interrupt line using request_irq kernel API and how to implement an interrupt handler ( e.g. my_interrupt_handlerin this example ) and how to pass a structure with some values from module to IRQ handler.

This code is almost self explainatory with added comments inline. If you want to know ” What is the difference between setup_irq and request_irq in Linux kernel interrupts ” ?

[bash]
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/moduleparam.h>
 
// execute it as
// sudo insmod ./interrupt.ko interupt_name="some_name" irq=1
// for testing use irq numbers from cat /proc/interrupts
 
// remove module as
// sudo rmmod interrupt
 
static int irq;
static char *interrupt_name;
 
module_param(interrupt_name, charp,0);
MODULE_PARM_DESC(interrupt_name, "Name for the Interrupt");
module_param(irq, int, 0);
MODULE_PARM_DESC(irq, "The IRQ of the network interface");
 
struct info_to_pass {
    int *some_int;
    char *some_string;
}dev_info;
 
static irqreturn_t my_interrupt_handler(int irq, void *dev_id) {
    static int mycount = 0;
    // info is what we passed as &dev_info to request_irq
    // this variable is just a argument carrier from module_init to IRQ handler.
    struct info_to_pass *info = dev_id;
 
    // static counter to just print debug message 10 times,
    // saying we received interrupt, after 10, we don't print anything
    // but interrupt might have came.
    if (mycount < 10) {
        printk("We received from module init : %s\n", info->some_string);
        printk("Interrupt! = %d\n", mycount);
        mycount++;
    }
 
    return IRQ_HANDLED;
}
 
static int __init mymodule_init(void) {
    printk ("My module initialised!\n");
 
/* request_irq: allocate a given interrupt line */
// int request_irq(unsigned int irq,
//                irq_handler_t handler,
//                unsigned long flags,
//                const char *name,
//                void *dev)
    dev_info.some_string = "helloworld";
 
    if (request_irq(irq, &my_interrupt_handler, IRQF_SHARED, interrupt_name, &dev_info)) {
        printk(KERN_ERR "myirqtest: cannot register IRQ %d\n", irq);
        return -EIO;
    }
 
//The second parameter, handler, is a function pointer to the actual interrupt handler that services this interrupt. This function is invoked whenever the operating system receives the interrupt.
 
// IRQF_SHARED. This flag specifies that the interrupt line can be shared among multiple interrupt handlers. Each handler registered on a given line must specify this flag; otherwise, only one handler can exist per line.
 
    printk("Request on IRQ %d succeeded\n", irq);
    return 0;
}
 
static void __exit mymodule_exit(void) {
    free_irq(irq, &dev_info);
    printk("Freeing IRQ %d\n", irq);
 
    printk ("Unloading my module.\n");
    return;
}
 
module_init(mymodule_init);
module_exit(mymodule_exit);
 
MODULE_LICENSE("GPL");

The Simple makefile to compile this driver on Linux laptop is as follows,

obj-m += interrupt.o

all:
        make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
        make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

Compile the driver as,


Subscribe with Valid Email Id to receive updates in Inbox. ( Secured by Google FeedBurner )

   


 $ make 
 $ sudo insmod ./interrupt.ko interrupt_name=somename irq=30 

Currently we have chosen random shared IRQ number 30 for testing to make sure we receive actual interrupt ( As in our driver, we dont consider real hardware interrupt with unique IRQ pin ) from /proc/interrupt

More Reference – https://notes.shichao.io/lkd/ch7/

lynxbee_ezoic

Leave a Comment

Android Android Build system Android Commands Android Java Applications Application Libraries Application Stack / User Interface Bash / Shell Scripts Bluetooth driver Cloud Technologies Commands and Packages Compilation Content Management System Core Kernel C Programs Development & Build Development, Debugging and Performance Tools Development Environment Setup Django & REST Api Errors & Failures Git Hardware Platforms HTML JAVA Programs Linux, OS Concepts and Networking Linux Device Drivers Linux Host, Ubuntu, SysAdmin Linux Kernel Linux Networking Middleware Libraries, HAL Multimedia Audio, Video, Images NDK / Middleware / HAL OS Concepts PHP Programming Languages Scripting and Automation Search Engine Optimisation ( SEO ) Social Media Source Code Management ( SCM ) System Administration, Security Testing and Debugging Uncategorized Web design and development Website Hosting Wordpress Yocto / Bitbake / Openembedded