当ISR运行并且发生另一个中断时会发生什么? [英] What happens when an ISR is running and another interrupt happens?

查看:217
本文介绍了当ISR运行并且发生另一个中断时会发生什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果ISR正在运行并且发生另一个中断会发生什么?第一次中断会被打断吗?第二个中断会被忽略吗?还是在完成第一个ISR后触发?

What happens if an ISR is running, and another interrupt occurs? Does the first interrupt get interrupted? Will the second interrupt get ignored? Or will it fire when the first ISR is done?

编辑 我忘了将它包含在问题中(但我将其包含在标签中),我想问的是这在Atmel AVR上是如何工作的.

EDIT I forgot to include it in the question (but I included it in the tags) that I meant to ask how this worked on Atmel AVR's.

推荐答案

通常,在大多数系统中,中断服务例程会一直进行到完成为止.但是,如果我们有一个较大的系统,其中几个设备可能会中断微处理器,则可能会出现优先级问题.

Normally, an interrupt service routine proceeds until it is complete without being interrupted itself in most of the systems. However, If we have a larger system, where several devices may interrupt the microprocessor, a priority problem may arise.

如果同时在当前中断中设置中断允许标志,那么您可以允许其他优先级比正在执行的中断更高的中断.此中断中断"称为嵌套中断.通过停止执行原始服务例程并在堆栈中存储另一个寄存器序列来解决该问题.这类似于嵌套子例程.由于每个中断自动使堆栈指针递减,而随后由RETURN指令自动递增,因此在第二个中断完成后,将恢复第一个中断服务程序,并以正确的顺序对这些中断进行服务.中断可以嵌套到任何深度,仅受堆栈可用的内存量限制.

If you set the interrupt enable flag within the current interrupt as well, then you can allow further interrupts that are higher priority than the one being executed. This "interrupt of an interrupt" is called a nested interrupt. It is handled by stopping execution of the original service routine and storing another sequence of registers on the stack. This is similar to nested subroutines. Because of the automatic decrementing of the stack pointer by each interrupt and subsequent incrementing by the RETURN instruction, the first interrupt service routine is resumed after the second interrupt is completed, and the interrupts are serviced in the proper order. Interrupts can be nested to any depth, limited only by the amount of memory available for the stack.

例如,在下图中,线程A正在运行.中断IRQx使中断处理程序Intx运行,该中断处理程序被IRQy及其处理程序Inty抢占. Inty返回一个事件,导致线程B运行; Intx返回一个导致线程C运行的事件.

For example, In the following diagram, Thread A is running. Interrupt IRQx causes interrupt handler Intx to run, which is preempted by IRQy and its handler Inty. Inty returns an event causing Thread B to run; Intx returns an event causing Thread C to run.

图片参考

对于硬件中断,优先级中断控制器芯片(PIC)是旨在使设备向CPU展示自己的地址的任务变得简单的硬件芯片. PIC还评估与其连接的设备的优先级.也可以对现代PIC进行编程,以防止产生低于所需级别的中断.

For hardware interrupts, Priority Interrupt Controller Chips (PIC's) are hardware chips designed to make the task of a device presenting its own address to the CPU simple. The PIC also assesses the priority of the devices connected to it. Modern PIC's can also be programmed to prevent the generation of interrupts which are lower than a desired level.

在输入中断向量之前, AVR硬件会清除 SREG 中的全局中断标志.因此,在处理程序退出之前,正常的中断将保持禁用状态,直到处理程序退出为止, RETI指令(由编译器作为中断处理程序的正常函数结尾的一部分发出)最终将进一步重新启用中断.因此,中断处理程序通常不嵌套.对于大多数中断处理程序而言,这是理想的行为,对于某些行为,甚至是为了防止无限递归中断(例如UART中断或级别触发的外部中断)所必需的.

The AVR hardware clears the global interrupt flag in SREG before entering an interrupt vector. Therefore, normally interrupts remain disabled inside the handler until the handler exits, where the RETI instruction (that is emitted by the compiler as part of the normal function epilogue for an interrupt handler) will eventually re-enable further interrupts. For that reason, interrupt handlers normally do not nest. For most interrupt handlers, this is the desired behaviour, for some it is even required in order to prevent infinitely recursive interrupts (like UART interrupts, or level-triggered external interrupts).

在极少数情况下,尽管可能希望通过在中断处理程序中尽早重新启用全局中断标志来实现嵌套中断,以便不延迟其他任何中断中断比绝对需要更多.可以在中断处理程序的开始处使用 sei()指令来完成此操作,但这仍然使编译器生成的函数序言中没有多少指令可以在禁用全局中断的情况下运行.通过以下方式声明处理程序,可以指示编译器在中断处理程序的开始处插入SEI指令:

In rare circumstances though nested interrupts might be desired by re-enabling the global interrupt flag as early as possible in the interrupt handler, in order to not defer any other interrupt more than absolutely needed. This could be done using an sei() instruction right at the beginning of the interrupt handler, but this still leaves few instructions inside the compiler-generated function prologue to run with global interrupts disabled. The compiler can be instructed to insert an SEI instruction right at the beginning of an interrupt handler by declaring the handler the following way:

ISR(XXX_vect, ISR_NOBLOCK)
{
  ...
}

其中XXX_vect是适用于MCU类型的有效中断向量的名称.

where XXX_vect is the name of a valid interrupt vector for the MCU type.

此外,请查看此应用说明,以获取有关Atmel中断的更多信息AVR.

Also, have a look at this Application Note for more info on interrupts on Atmel AVRs.

这篇关于当ISR运行并且发生另一个中断时会发生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆