ret = request_irq(chip->irq, xxx_intr_handler,
IRQF_TRIGGER_FALLING | IRQF_NO_THREAD |
IRQF_NO_SUSPEND, name, chip);
上面是中断初始化中调用系统中断请求函数,查看函数原型:
/*
static inline int __must_check
request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
const char *name, void *dev)
{
return request_threaded_irq(irq, handler, NULL, flags, name, dev);
}
*/
其中,中断触发标志中需要根据硬件对应设计选择正确触发类型。
基本类型:
IRQF_TRIGGER_HIGH
IRQF_TRIGGER_LOW
IRQF_TRIGGER_FALLING
IRQF_TRIGGER_RISING
对应基本触发类型:高电平触发,低电平触发,下降沿触发,上升沿触发。
除此之外,看到其他驱动还有另外一种禁止打断型中断:ONESHOT类型
ret = devm_request_threaded_irq(&pdev->dev, alm_irq, NULL,
da9055_rtc_alm_irq,
IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
"ALM", rtc);
中断标志位 IRQF_ONESHOT
one shot本身的意思的只有一次的,结合到中断这个场景,则表示中断是一次性触发的,不能嵌套。对于primary handler,当然是不会嵌套,但是对于threaded interrupt handler,我们有两种选择,一种是mask该interrupt source,另外一种是unmask该interrupt source。
一旦mask住该interrupt source,那么该interrupt source的中断在整个threaded interrupt handler处理过程中都是不会再次触发的,也就是one shot了。这种handler不需要考虑重入问题。
具体是否要设定one shot的flag是和硬件系统有关的,我们举一个例子,比如电池驱动,电池里面有一个电量计,是使用HDQ协议进行通信的,电池驱动会注册一个threaded interrupt handler,在这个handler中,会通过HDQ协议和电量计进行通信。对于这个handler,通过HDQ进行通信是需要一个完整的HDQ交互过程,如果中间被打断,整个通信过程会出问题,因此,这个handler就必须是one shot的。
本文分析了Linux内核中断请求函数`request_irq`的使用,特别是`IRQF_ONESHOT`标志位的作用。`IRQF_ONESHOT`表示一次性触发的中断,不允许嵌套。中断处理程序在处理过程中会屏蔽中断源,防止中断重入,这对于某些需要完整交互过程的驱动,如电池驱动与电量计的HDQ通信,是必要的。选择是否使用`IRQF_ONESHOT`取决于硬件系统特性。
564

被折叠的 条评论
为什么被折叠?



