按键按下(产生了中断)→跳转到异常向量入口,执行中断函数
中断函数要做什么:
1.保护现场
2.执行中断处理函数
3.恢复现场
我们需要做什么?
学会使用中断注册函数,了解注册中断相关的函数和结构体
中断注册函数 request_irq // 各种Linux下都通用的函数
request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev) { return request_threaded_irq(irq, handler, NULL, flags, name, dev); }
参数1:irq,中断号。(和平台架构相关,结合datasheet以及平台文件)
参数2:中断处理函数
参数3:中断标记。上升/下降沿,高/低电平……
参数4:中断名字。cat /proc/interrupts
参数5:使用设备的设备结构体或者NULL。free_irq也用到
中断注册函数 free_irq
void free_irq(unsigned int irq, void *dev_id)
4412上外部中断号如何对应:(IRQ_EINT(x)和datasheet对应)
HOME和BACK
EXYNOS4_GPX1[1]和EXYNOS4_GPX1[2]
→KP_COL[1]和KP_COL[2]
→XEINT_9和XEINT_10
中断号: RQ_EINT(9)和IRQ_EINT(10) //对中断的统一处理,主中断和次中断
流程:1.在platform中注册文件设备
在平台文件中注册设备:keyirq
添加:
struct platform_device s3c_device_keyirq_ctl = {
.name = "keyirq",
.id = -1,
};
&s3c_device_keyirq_ctl,
#include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <mach/gpio.h> #include <plat/gpio-cfg.h> #include <linux/miscdevice.h> #include <linux/platform_device.h> //#include <mach/gpio-bank.h> #include <mach/regs-gpio.h> #include <asm/io.h> #include <linux/regulator/consumer.h> //#include "gps.h" #include <linux/delay.h> //中断头文件 #include <linux/irq.h> #include <linux/interrupt.h> #define DPRINTK(x...) printk("keyirq DEBUG:" x) #define DRIVER_NAME "keyirq" static irqreturn_t eint9_interrupt(int irq,void *dev_id) { printk("receive a interrupt 9! "); return IRQ_HANDLED; } static irqreturn_t eint10_interrupt(int irq,void *dev_id) { printk("receive a interrupt 10! "); return IRQ_HANDLED; } static int keyirq_probe(struct platform_device *pdev) { //int ret, i; char *banner = "keyirq Initialize "; printk(banner); //注册中断 request_irq(IRQ_EINT(9),eint9_interrupt,IRQ_TYPE_EDGE_FALLING,"my_eint9",pdev); request_irq(IRQ_EINT(10),eint10_interrupt,IRQ_TYPE_EDGE_FALLING,"my_eint10",pdev); return 0; } static int keyirq_remove (struct platform_device *pdev) { free_irq(IRQ_EINT(9),pdev); free_irq(IRQ_EINT(10),pdev); return 0; } static int keyirq_suspend (struct platform_device *pdev, pm_message_t state) { DPRINTK("keyirq suspend:power off! "); return 0; } static int keyirq_resume (struct platform_device *pdev) { DPRINTK("keyirq resume:power on! "); return 0; } static struct platform_driver keyirq_driver = { .probe = keyirq_probe, .remove = keyirq_remove, .suspend = keyirq_suspend, .resume = keyirq_resume, .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, }, }; static void __exit keyirq_exit(void) { platform_driver_unregister(&keyirq_driver); } static int __init keyirq_init(void) { return platform_driver_register(&keyirq_driver); } module_init(keyirq_init); module_exit(keyirq_exit); MODULE_LICENSE("Dual BSD/GPL");