中断是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序,处理完毕后又返回原被暂停的程序继续运行。
在 Linux 中,中断处理是操作系统与硬件设备之间通信的重要方式之一。Linux 内核中的中断处理程序负责响应硬件设备发出的中断信号,并执行相应的处理;
Linux 中断处理的一般流程:
硬件中断触发->中断控制器响应->中断处理程序调用->中断处理->中断处理程序完成
在驱动程序中实现中断:
1、获取中断号
2、请求中断
request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char * name, void * dev);
参数1:中断号
参数2:中断处理函数
参数3:中断类型
参数4:中断处理函数的标识名称
参数5:设备指针
3、中断处理函数
函数指针定义
typedef irqreturn_t (*irq_handler_t)(int, void *);
3、释放中断请求
free_irq(unsigned int irq, void * dev_id);
举个例子:
#include <linux/init.h>
#include <linux/module.h>#define GPIO_BUTTON_PIN 40static unsigned int irq_num;// 中断处理函数
static irqreturn_t key_irq_handler(int irq, void *dev_id)
{int value = gpio_get_value(GPIO_BUTTON_PIN);if (!value) {printk("--------key press-------\n");} else {printk("--------key up----------\n")}return IRQ_HANDLED;
}static int __init key_drv_init(void) {int ret;// 获取中断号// 请求 GPIO 引脚ret = gpio_request(GPIO_BUTTON_PIN, "key_gpio");if (ret) {printk(KERN_ERR "Failed to request GPIO pin\n");return ret;}// 设置 GPIO 引脚方向为输入ret = gpio_direction_input(GPIO_BUTTON_PIN);if (ret) {printk(KERN_ERR "Failed to set GPIO pin direction\n");gpio_free(GPIO_BUTTON_PIN);return ret;}// 将 GPIO 映射到 IRQirq_num = gpio_to_irq(GPIO_BUTTON_PIN);if (irq_num < 0) {printk(KERN_ERR "Failed to map GPIO to IRQ\n");gpio_free(GPIO_BUTTON_PIN);return irq_num;}// 请求中断ret = request_irq(irq_num, key_irq_handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "key_irq", NULL);if (ret) {printk(KERN_ERR "Failed to register IRQ handler\n");gpio_free(GPIO_BUTTON_PIN);return ret;}return 0;
}static void __exit key_drv_exit(void) {free_irq(irq_num, NULL);gpio_free(GPIO_BUTTON_PIN);
}module_init(key_drv_init);
module_exit(key_drv_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("dengcaixiang");
MODULE_DESCRIPTION("Simple key driver");
代码中实现了gpio按键中断,设备运行效果如下: