字符设备驱动程序之中断方式的按键驱动_Linux中断处理结构(七)

字符设备驱动程序之中断方式的按键驱动_Linux中断处理结构


解析asm_do_IRQ,了解中断处理,怎么进行的。



单片机下的中断处理:

1、分辨是哪一个中断

2、调用处理函数

3、清中断



Linux内核:

asm_do_IRQ(C函数入口)最终 调用到 事先初始化的handle_irq函数。


以上单片机的三项,是用asm_do_IRQ函数来实现的。


1、参数irq:中断号。

2、irq_desc:是一个数组。


irq_desc[NR_IRQS]:中断描述数组,以中断号NR_IRQS为下标。

3、desc_handle_irq(irq, desc)进入处理


desc就是irq_desc[irq]。irq_desc全局数组,以irq中断号为下标的数组项。

分辨是哪一个中断;调用处理函数;清中断,这三项内容就是在handle_irq里实现的。

4、irq_desc:

hadle_irq,chip。
5、初始化:s3c24xxx_init_irq函数:

所以:

外部中断0:IRQ_EINT0=16,irq=16,找到数组项,然后进行赋值。

数组irq_desc[EINT0~EINT3]

{

    handle_irq = handle_edge_irq;

    chip = s3c_irq_eint0t0t4;

}

数组irq_desc[EINT4~EINT23]

    handle_irq = handle_edge_irq;

    chip = s3c_irqext_chip;

}

6、处理边缘出发中断    handle_edge_irq函数:

(1) desc->chip->ack(irq):清中断

(2) hadle_irq_event:处理中断(取出action链表中的成员,执行action->handle(处理函数))


 action是一个链表,action=action->next,ret=action->handler,取出链表的各种成员,然后调用它们的hadler函数



总结:

发生中断之后,按下按键:

中断的框架:

1、CPU自动进入异常模式

    b vector_irq + stubs_offset        (vector_irq是一个宏来定义的)

2、然后调用到  __irq_usr

3、最终调用到  b asm_do_IRQ

4、irq_desc[irq]->handler_irq           (以中断号为下标,取出一项handler_irq)

5、handler_irq = handler_edge_irq (处理边缘中断函数)

    (1) desc->chip->ack(irq):清中断

    (2) hadle_irq_event:处理中断(取出action链表中的成员,一 一执行action->handle(处理函数))

6、irq_desc 结构体:

(1)函数指针 handle_irq  指向  handle_edge_irq。

(2)action 中断动作链表,链表头,

链表结构体:irqaction(用户注册的中断处理函数)


handler:处理函数


(3)芯片相关的底层处理函数 chip  指向  s3c_irq_eint0t4 、s3c_irqext_chip。


startup、shutdown 启动 关闭这个中断。ennable、disable 使能、禁止中断。ack 响应中断(清中断)。


linux内核中断体系架构:




执行我们自己的中断处理函数:

action->handler

就是在链表里面,把irqaction结构填进去。


告诉内核处理函数是什么!!

request_irq():


int request_irq(unsigned int irq, irq_handler_t handler, unsigned long irqflags, const char *devname, void *dev_id)

irq:中断号

handler:处理函数

irqflags:上升沿触发、下降沿触发、边沿触发

devname:中断的名字

devid:

request_irq函数:

(1)、分配一个irqaction结构,结构里面的成员都指向参数

(2)、设置中断,setup_irq(irq,action)

            a.在irq_desc[irq]->action链表,加入刚传进来的action

            b.desc->chip->settype(),把对应的引脚设置为中断引脚

            c.desc->chip->startup / enable,使能中断


不想使用中断:


free_irq(irq,dev_id)



总结这两个函数:

注册中断服务程序 

request_irq(irq, handler, flags, name, dev_id)

分配一个irqaction结构,指向参数;

把这个结构放入irq_desc[irq]数组项 的 action链表里;

设置引脚,使能中断


释放

free_irq(irq, dev_id)

出链(从链表里拖出来)

禁止中断(什么时候禁止呢? 如果链表里没有irqaction结构成员了,就会关闭中断。如果原来有两个,free掉一个,就不会禁止中断)


猜你喜欢

转载自blog.csdn.net/xiaodingqq/article/details/80298933