如果ISR正在运行,会发生另一个中断,会发生什么?第一个中断是否被中断?第二个中断会被忽略吗?或者在第一次ISR完成后会发射吗?
修改 我忘了将它包含在问题中(但我将其包含在标签中),我想问一下这对Atmel AVR有何影响。
答案 0 :(得分:27)
通常情况下,中断服务程序会继续执行,直到完成,而不会在大多数系统中自行中断。但是,如果我们有一个更大的系统,多个设备可能会中断微处理器,则可能会出现优先级问题。
如果在当前中断中设置中断使能标志,则可以允许进一步的中断更高优先级比正在执行的中断更强。这种“中断中断”称为嵌套中断。它通过停止执行原始服务例程并在堆栈上存储另一个寄存器序列来处理。这类似于嵌套子例程。由于每个中断自动递减堆栈指针并随后通过RETURN指令递增,因此在第二个中断完成后恢复第一个中断服务程序,并按正确的顺序处理中断。中断可以嵌套到任何深度,仅受可用于堆栈的内存量的限制。
例如,在下图中,线程A正在运行。中断IRQx导致中断处理程序Intx运行,它被IRQy及其处理程序Inty抢占。 Inty返回一个导致线程B运行的事件; Intx返回一个导致线程C运行的事件。
对于硬件中断,优先级中断控制器芯片(PIC)是硬件芯片,旨在使设备的任务简单地向CPU显示其自己的地址。 PIC还评估连接到它的设备的优先级。现代PIC也可以编程,以防止产生低于期望水平的中断。
AVR硬件会在输入中断向量之前清除 SREG 中的全局中断标志。因此,通常中断在处理程序内部保持禁用,直到处理程序退出,其中 RETI指令(由编译器作为中断处理程序的正常函数结尾的一部分发出)最终将重新启用中断。因此,中断处理程序通常不会嵌套。对于大多数中断处理程序,这是所需的行为,对于某些行为甚至是必需的,以防止无限递归中断(如UART中断或电平触发的外部中断)。
在极少数情况下,虽然在中断处理程序中尽早重新启用全局中断标志可能需要嵌套中断,但为了不推迟任何其他中断超过绝对需要。这可以在中断处理程序的开头使用 sei()指令来完成,但这仍然会在编译器生成的函数序言中留下很少的指令,以便在禁用全局中断的情况下运行。可以通过以下方式声明处理程序,指示编译器在中断处理程序的开头插入SEI指令:
ISR(XXX_vect, ISR_NOBLOCK)
{
...
}
其中XXX_vect是MCU类型的有效中断向量的名称。
另外,请查看此Application Note以获取有关Atmel AVR中断的更多信息。
答案 1 :(得分:5)
中断的工作方式:
代码设置“全局中断使能”位;没有它,就不会发生中断。
当某些事情发生中断时,会设置一个标志。
当注意到中断标志时,“全局中断使能”位清零。
运行适当的ISR。
重置“全局中断使能”位。
现在回到步骤2,,除非在ISR期间已经设置了中断标志;然后事情又回到第3步。
所以回答这个问题:当第一个ISR完成后,第二个ISR将会运行。
希望这有帮助!