- UID
- 1029342
- 性别
- 男
|
中断处理函数的编写与注册
驱动人员在设计中断处理函数时,要遵循的要求是:
(1)可嵌套不可重入
(2)不能睡眠
(3)如果硬件有中断的状态寄存器,软件要负责清除中断的标志位。一般来说,如果不清除标志位,设备无法再次产生中断
(4)中断处理函数的注册和注销
0.前提
需要包含的头文件
#include <linux/interrupt.h>
#include <mach/irqs.h> //片内外设
#include <linux/gpio.h> //片外外设
#include <mach/gpio.h>
1.确定中断号
正如刚才如上所述:如果是外部IO中断,那么我们可以通过GPIO号获取中断号:
eg:#define KEY_IRQ gpio_to_irq(gpio号);
2.中断处理函数编写
中断处理函数的格式:
eg:
//参数1:int irq :中断号
//参数2:void * dev_id :为传递给中断处理函数的参数
//返回值:IRQ_NONE:中断不是由本设备引起的
IRQ_HANDLED:中断是由本设备引起的
static irqreturn_t key_service(int irq, void *dev_id)
{
//根据硬件要求完成相应工作
...
return IRQ_HANDLED 或 IRQ_NONE;
}
3.注册中断处理函数(必须检查返回值)
u32 flags = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING;//定义中断的标志:下降沿/上升沿/低电平/高电平触发中断
int ret;
ret = request_irq( KEY_IRQ, /* 中断号 */
key_service, /* 中断处理函数 */
flags, /* 中断的标志 */
"xxx", /* 中断处理函数的名字 */
dev_id);/* dev_id为传给中断处理函数的参数,一般会设置为私有结构体的指针,非共享>中断可以为NULL */
if (ret) {
printk("Cannot register interrupt handler\n");
return -1;
}
4.注销中断处理函数
free_irq(irq, dev_id); //参数为中断号和dev_id。 dev_id一定要和request_irq中的最后一个参数一致
5.屏蔽中断
1.可以人为关闭(mask)/打开某个中断:
disable_irq(int irq);
enable_irq(int irq);
这两个函数是可以嵌套的,也就是说,如果对一个中断disable了3次,需要调用enable函数3次才能打开对该中断的屏蔽;
2.还可以屏蔽本cpu的中断:
local_irq_disable();
local_irq_enable(); |
|