1、安装中断处理例程
#include <linux/sched.h>
int request_irq(unsigned int irq, //正确时返回0
irqreturn_t (*handler) (int, void *, struct pt_regs *),
unsigned long flags,
const char *dev_name,
void *dev_id);
void free_irq(unsigned int irq, void *dev_id);
可以在flags中设置的位如下:
SA_INTERRUPT:
SA_SHIRQ:
SA_SAMPLE_RANDOM:
调用request_irq的正确位置应该是在设备第一次打开、硬件被告知产生中断之前。调用free_irq的位置是最后一次关闭设备、硬件被告知不再中断处理器之后。
注:i386和x86_64体系结构定义了如下函数,用于查询某个中断线是否可以用:
int can_request_irq(unsigned int irq, unsigned long flags);
//如果分配成功则返回非0值。
注:x86体系结构下定义的中断数量是224个
2、自动检测IRQ号
(1)内核帮助下的探测
Linux内核提供了一个底层设施来探测中断号,它只能工作在非共享的模式下。
#include <linux/interrupt.h>
unsigned long probe_irq_on(void);//返回的中断掩码传给probe_irq_off
int probe_irq_off(
unsigned long);//返回probe_irq_on之后发生的中断编号,若无中断发生则返回0,若有多个中断产生,则有二义性返回负值。
(2)DIY探测
3、禁用和启用中断
(1)禁用单个中断
#include <asm/irq.h>
void disable_irq(int irq);
void disable_irq_nosync(int irq);
void enable_irq(int irq);
注:不建议禁用中断线
(2)禁止所有的中断
void local_irq_save(unsigned long flags);
void local_irq_disable(void);
void local_irq_restore(unsigned long flags);
void local_irq_enable(void);
4、顶半部和底半部
(1)tasklet
必须使用宏DECLARE_TASKLET声明tasklet:
DECLARE_TASKLET(name, function, data);
//name是给tasklet起的名字,function是执行tasklet时调用的函数(带有unsigned long参数并返回void),data是传递给tasklet函数的unsigned long 类型的值。
(2)工作队列
声明并初始化:
static struct work_struct short_wq;
INIT_WORK(&short_wq, (void (*) (void * )) short_do_tasklet, NULL);
5、中断共享