clear_bit(irq, irqs_resend);
desc = irq_to_desc(irq);
local_irq_disable();
desc->handle_irq(desc);
local_irq_enable();
}
}
/* Tasklet to handle resend: */
static DECLARE_TASKLET(resend_tasklet, resend_irqs, 0);
1) irqs_resend是一个unsigned int类型的数组,每一个bit都代表一个irq是否resend。
2) resend_irqs是注册的resend_tasklet的callback函数,当tasklet_schedule(&resend_tasklet)之后就会被调度执行。
3) 在resend_irqs函数中,通过判断irqs_resend变量中的每一个bit位是否为1(即是否需要resend,也就是调用irq注册的中断handle)。
好了,现在可以解答清楚的解答第一个问题了:设备唤醒cpu之后是立即跳转中断向量表指定的位置吗?如果不是,那么是什么时候才会跳转呢?设备唤醒cpu之后并不是立即跳转中断向量执行中断,而是等到syscore_resume以及打开cpu中断之后才开始。第二个问题也有答案了,已经跳转到中断服务函数开始执行代码,后续就会调用你注册的中断handle 吗?如果不是,那中断服务函数做什么准备呢?而你注册的中断handle又会在什么时候才开始执行呢?第一次跳转执行中断仅仅是设置相关的flag并且disable_irq,在执行完成设备的resume noirq回调函数之后通过check_irq_resend中调度tasklet,最终执行注册的中断handle,至于为什么要这么做,前面分析也给了答案。
2.7. IRQ handler会睡眠吗?
你想过request_thread_irq函数注册的hardirq handler或者是threaded handler会执行一半时,系统会再一次的休眠下去吗?再看看2.2节的图,实际上对于所有已经打开的irq在suspend_device_irqs()会调用synchronize_irq()等待正在处理的hardirq handler或者threaded handler。synchronize_irq()代码如下:
void synchronize_irq(unsigned int irq)
{
struct irq_desc *desc = irq_to_desc(irq);
if (desc) {
__synchronize_hardirq(desc);
/*
* We made sure that no hardirq handler is
* running. Now verify that no threaded handlers are
* active.
*/
wait_event(desc->wait_for_threads,
!atomic_read(&desc->threads_active));
}
}
1)__synchronize_hardirq()是等待hardirq handler执行完毕。
2)只要threads_active计数不为0就,等待threaded handler执行完毕。
__synchronize_hardirq()代码如下:
static void __synchronize_hardirq(struct irq_desc *desc)
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-77052-7.html
没见过有人买
质检总局连买个东西都不知道怎么买
撞死他
很广泛