1、概述

(1)裸机中断处理流程回顾
(2)Linux中断处理流程分析
(3)Linux中断处理程序设计

 

2、裸机中断回顾

(1)中断有一个统一入口:中断向量表
(2)然后跳转到中断处理函数中,获取中断源编号,调用相应的处理函数asm_do_IRQ
(3)中断处理函数要事先注册到表中

 

3、中断处理程序的设计

(1)注册中断

int request(unsigned int irq,  void(*handler)(int, void*, struct pt_regs*), unsigned long flags,const char *name,void *dev_id)
返回0代表注册成功,其他失败。
参数分别是:中断号,处理函数,中断选项flags,设备名字,共享中断的标识id,
中断选项flags:IRQF_DISABLE 快速中断  IRQF_SHARED共享

(2)中断处理
注意中断上下文中不能有:不能有阻塞函数,不能有调度函数。
①首先检查设备是否产生中断
②清除中断产生标识
③相应的硬件操作

(3)注销中断
void free_irq(unsigned int irq, void *dev_id)

4、实例代码

#include <linux/module.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/miscdevice.h>

#if 0
struct miscdevice  {
        int minor;
        const char *name;
        const struct file_operations *fops;
        struct list_head list;
        struct device *parent;
        struct device *this_device;
        const struct attribute_group **groups;
        const char *nodename;
        umode_t mode;
};
#endif 
/**************引入中断框架**************/
#define GPFCON 0X56000050
irqreturn_t key_int(int irq, void *dev_id)
{
    /*1、检查是否发生了中断
    **2、清除中断
    **3、打印按键值
    */
    printk("key down\n");
    return 0;
}
void key_hw_init(void)
{
    unsigned int *gpio_config;
    unsigned short data;
    gpio_config=ioremap(GPFCON,4);
    data=readw(gpio_config);//读了4节,读出来再写进去
    data &= ~0b11;
    data |=0x10;
    writew(data,gpio_config);//将引脚配置成中断
}
/************************************/
int key_open(struct inode *node, struct file *filp)
{
    return 0;
}
struct file_operations key_fops={
    .open=key_open,
};

struct miscdevice key_miscdev = {
    .minor = 200,
    .name  = "key",
    .fops = &key_fops,
};

static int button_init()
{
    misc_register(&key_miscdev);//按键下降沿触发中断
    key_hw_init();
    request_irq(IRQ_EINT0,key_int, IRQF_TRIGGER_FALLING,"key",0);
}
static void button_exit()
{
    misc_deregister(&key_miscdev);
    free_irq(IRQ_EINT0, 0);//注销中断程序
}
MODULE_LICENSE("GPL");
module_init(button_init);//为甚改成key_init就报错
module_exit(button_exit);