【Linux内核驱动】按键中断

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wr132/article/details/78574561

中断注册函数: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对应

底板原理图

核心板原理图

准备工作

  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("[email protected]");


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);

猜你喜欢

转载自blog.csdn.net/wr132/article/details/78574561