编程相关
注册中断
int request_irq( unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev)
typedef irqreturn_t (*irq_handler_t)(int, void *);
IRQF_DISABLED
会禁用除本本身以外的其它中断,一般是不用的
IRQF_SAMPLE_RANDOM
可以帮助内核随机数的产生。如果中断产生地毫无规律,可以使用该标志
IRQF_TIMRE
专用于系统定时器中断
IRQF_SHARED
多个中断处理程序共享一条中断线(号),该标志较为常用
void *dev 用于共享中断线,每一个中断处理程序都应该对应自己唯一的 dev
返回值
0:成功 其它:失败 失败的原因:中断线被占用?
注意事项:request_irq函数可能会睡眠,不可在中断上下文中调用
注销中断
void free_irq(unsigned int irq, void *dev)
中断函数
static irqreturn_t irq_handler(unsigned int, void *)
返回值
IRQ_NONE
不是该设备产生的中断
IRQ_HANDLED
不是该设备产生的中断
注意事项:中断函数不会嵌套,不需处理重入
禁止和使能所有中断(当前处理器)
unsigned long flags; local_irq_save(flags); // 此处中断被关闭 local_irq_restore(flags);
注意:该段代码应位于同一栈帧中,即同一函数中。禁止和使能可嵌套。
禁止和使能单条中断线
// 禁止中断,当前中断处理程序完成后,该函数才返回 void disable_irq(unsigned int irq); // 禁止中断,立即返回 void disable_irq_nosync(unsigned int irq); // 使能中断 void enable_irq(unsigned int irq); // 等待中断程序返回 void synchronize_irq(unsigned int irq);
注意:disable_irq[_nosync] 和 enable_irq必须配套使用,并可以嵌套。
中断上下文
尽量节约内核栈空间,不要再函数内定义大数组等。