【Linux内核驱动】按键中断

时间:2020-12-01 23:36:59

中断注册函数:request_irq

request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
const char *name, void *dev)
参数1:irq,中断号。(和平台架构相关,结合datasheet以及平台文件)
参数2:中断处理函数
参数3:中断标记。上升/下降沿,高/低电平……
参数4:中断名字。cat /proc/interrupts
参数5:使用设备的设备结构体或者NULL。free_irq
free_irq(irq,*dev_id)

4412上外部中断号如何对应

在平台文件(arch/arm/plat-s5p/include/plat/irqs.h)中定义了IRQ_EINT(),IRQ_EINT(x)和原理图以及datasheet对应

【Linux内核驱动】按键中断

【Linux内核驱动】按键中断

准备工作

  1. 在平台文件中注册设备:key_irq,添加:

    struct platform_device s3c_device_keyirq_ctl = {
    .name = "key_irq",
    .id = -1,
    };
    &s3c_device_keyirq_ctl,
  2. 重新编译烧写内核

编码工作

  1. 在led的基础上修改
  2. 添加request_irq、free_irq以及中断处理函数

记得去掉GPIO_BUTTON以及添加平台文件
通过命令: cat /proc/interrupts查看中断

代码

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <mach/irqs.h>

#define DRIVER_NAME "key_irq"

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("colorfulshark@hotmail.com");


static int key_irq_probe(struct platform_device *device);
static int key_irq_remove(struct platform_device *device);
static struct platform_driver key_irq_driver = {
.probe = key_irq_probe,
.remove = key_irq_remove,
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
},
};

/* define irq handler */

static irqreturn_t key_irq_handler(int irq, void *device)
{
printk("you pressed home buttom(EINT9)\n");
return IRQ_HANDLED;
}





/* define platform driver functions */

static int key_irq_probe(struct platform_device *device)
{
int error;
printk("key irq probe\n");
printk("request irq\n");
error = request_irq(IRQ_EINT(9), key_irq_handler, IRQF_TRIGGER_FALLING, "ket_eint9", device);
if(error < 0)
goto err_req_irq;
return 0;

err_req_irq:
printk("failed to request irq\n");
return error;
}

static int key_irq_remove(struct platform_device *device)
{
printk("key irq remove\n");
printk("free irq\n");
free_irq(IRQ_EINT(9), device);
return 0;
}

static int key_irq_init(void)
{
int error;
printk("key irq init\n");
error = platform_driver_register(&key_irq_driver);
if(error < 0)
goto err_plat_dri_reg;
return 0;

err_plat_dri_reg:
printk("failed to register platform driver\n");
return error;
}

static void key_irq_exit(void)
{
printk("key irq exit\n");
platform_driver_unregister(&key_irq_driver);
}

module_init(key_irq_init);
module_exit(key_irq_exit);