中断注册函数: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对应
准备工作
-
在平台文件中注册设备:key_irq,添加:
struct platform_device s3c_device_keyirq_ctl = {
.name = "key_irq",
.id = -1,
};
&s3c_device_keyirq_ctl, 重新编译烧写内核
编码工作
- 在led的基础上修改
- 添加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);