您的位置:首页 > 其它

中断处理函数中不用disable_irq而…

2013-12-19 20:51 330 查看
今天在写触摸屏驱动时在中断处理函数中使用disable_irq关中断发现在进入中断处理后内核就挂掉了,于是研究了一下才发现disable_irq关闭中断并等待中断处理完后返回,
而disable_irq_nosync立即返回. 在中断处理程序中应该使用disable_irq_nosync来关闭中断

先看一下disable_irq_nosync,内核代码中是这样解释的:

/**

*    disable_irq_nosync
- disable an irq without
waiting

*    @irq:
Interrupt to disable

*

*    Disable
the selected interrupt line.
Disablesand Enables are

*    nested.

*    Unlike
disable_irq(),this
function doesnot ensure
existing

*    instances
of the IRQ handler have
completed before returning.

*

*    This
function may be called from IRQ context.

*/

void disable_irq_nosync(unsigned
int irq)

{

struct
irq_desc *desc = irq_to_desc(irq);

unsigned
long flags;

if
(!desc)

return;

chip_bus_lock(irq,
desc);

spin_lock_irqsave(&desc->lock,
flags);

__disable_irq(desc,
irq, false);

spin_unlock_irqrestore(&desc->lock,
flags);

chip_bus_sync_unlock(irq,
desc);

}

关闭中断后程序返回,
如果在中断处理程序中, 那么会继续将中断处理程序执行完.

void disable_irq(unsignedint irq)

{

struct
irq_desc *desc = irq_desc + irq;

if
(irq>=
NR_IRQS)

return;

disable_irq_nosync(irq);

if
(desc->action)

synchronize_irq(irq);

}

关闭中断并等待中断
处理完后返回.从代码中可以看到, disable_irq先是调用了disable_irq_nosync,
然后检测desc->action是否为1. 在中断处理程序中, action是置1的,
所以进入synchronize_irq函数中.

void synchronize_irq(unsignedint irq)

{

struct
irq_desc *desc= irq_to_desc(irq);

unsigned
int status;

if
(!desc)

return;

do
{

unsigned long flags;

while (desc->status& IRQ_INPROGRESS)

cpu_relax();

spin_lock_irqsave(&desc->lock,
flags);

status = desc->status;

spin_unlock_irqrestore(&desc->lock,
flags);

} while (status & IRQ_INPROGRESS);

wait_event(desc->wait_for_threads,!atomic_read(&desc->threads_active));

}

注释中说明该函数是在等待中断处理程序的结束, 这也是disable_irq与disable_irq_nosync不同的主要所在.
但是在中断处理函数中调用会发生什么情况呢? 进入中断处理函数前IRQ_INPROGRESS会被__setup_irq设置,
所以程序会一直陷在while循环中, 而此时内核以经被独占, 这就导致系统死掉.

总结:

由于在disable_irq中会调用synchronize_irq函数等待中断返回,
所以在中断处理程序中不能使用disable_irq,
否则会导致cpu被synchronize_irq独占而发生系统崩溃.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: