Arduino 上的中断会中断其他中断吗?
我有一个 Arduino Uno (很棒的小设备!)。它有两个中断;我们将它们称为0 和1。我使用 attachInterrupt()
将一个处理程序附加到中断 0,并将另一个处理程序附加到中断 1:http://www.arduino.cc/en/Reference/AttachInterrupt。
中断 0 被触发并调用其处理程序,该处理程序会进行一些数字运算。如果中断1被触发时,中断0的处理程序仍在执行,会发生什么?
中断1会中断中断0,还是中断1会等待直到中断0的处理程序执行完毕?
请注意,这个问题特别与 Arduino 有关。
I have an Arduino Uno (awesome little device!). It has two interrupts; let's call them 0 and 1. I attach a handler to interrupt 0 and a different one to interrupt 1, using attachInterrupt()
: http://www.arduino.cc/en/Reference/AttachInterrupt.
Interrupt 0 is triggered and it calls its handler, which does some number crunching. If interrupt 0's handler is still executing when interrupt 1 is triggered, what will happen?
Will interrupt 1 interrupt interrupt 0, or will interrupt 1 wait until interrupt 0's handler is done executing?
Please note that this question specifically relates to Arduino.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在 Arduino(又名 AVR)硬件上,嵌套中断不会发生,除非您有意创建允许其发生的条件。
来自 avr-lib:
(来源:http://linux.die.net/man/3/avr_interrupts)
On Arduino (aka AVR) hardware, nested interrupts don't happen unless you intentionally create the conditions to allow it to happen.
From avr-lib:
(source: http://linux.die.net/man/3/avr_interrupts )
除非您专门在 ISR(中断服务例程)内重新启用中断,否则当前正在运行的任何中断都会在处理下一个中断之前完成,再加上一条机器代码指令。
大多数中断会在处理器内部设置一个标志,该标志会在指令之间进行检查,以查看是否应处理该中断。按优先顺序检查标志。在 Uno 上是:(
请注意,重置不能被屏蔽)。
可以想象,低级中断可能正在进行中(例如 TIMER0_OVF_vect)。当它忙于执行任务时,可能会发生多个其他中断事件(并设置 CPU 中的相应位)。它们将按上述顺序提供服务,而不是按实际发生的时间顺序。
可以写入硬件寄存器来取消挂起的中断 - 即清除标志。
之所以提到“多一条机器代码指令”,是因为处理器被设计为保证当它从不使能中断转换到使能中断时,总是会多执行一条指令。
这使您可以编写如下代码:
如果没有这样的代码,在进入睡眠状态之前可能会发生中断。这意味着您永远不会醒来,因为您依赖于睡眠期间发生的中断,而不是之前发生的中断。
这就是为什么我更喜欢
interrupts
和noInterrupts
的助记符,因为它们的意图是非常清楚。这些是通过核心包含文件中的定义来实现的。Unless you specifically re-enable interrupts inside an ISR (Interrupt Service Routine) then whatever interrupt is currently running completes, plus one more machine code instruction, before the next interrupt is serviced.
Most interrupts set a flag inside the processor, which is checked between instructions, to see if the interrupt should be serviced. Flags are checked in priority order. On the Uno that is:
(Note that Reset cannot be masked).
Conceivably a low-level interrupt might be in progress (eg. TIMER0_OVF_vect). While that is busy doing its stuff multiple other interrupt events might occur (and set the corresponding bits in the CPU). They will be serviced in the above order, not in the order in which they actually occur in time.
There are hardware registers that can be written to, to cancel a pending interrupt - that is, to clear the flag.
The reason for mentioning "one more machine code instruction" is that the processor is designed to guarantee that when it transitions from interrupts not enabled, to interrupts enabled, one more instruction is always executed.
This lets you write code like this:
Without that, an interrupt might occur before going to sleep. Which means you never wake, because you were relying upon the interrupt occuring during sleep, not before it.
That is why I prefer the mnemonics of
interrupts
andnoInterrupts
because the intent there is very clear. These are implemented by defines in the core include files.文档提到Arduino中断具有优先级:
它还提供了附加信息的链接:
根据什么是中断优先级?和禁用中断时是否会发生中断?,我们可以得出结论:
所以,不同的中断不会互相中断。它们将根据其优先级被执行。
The documentation mention that Arduino interrupts have priority:
It also provides a link for additional information:
According to sections What is interrupt priority? and Can interrupts occur while interrupts are disabled?, we can conclude that:
So, different interrupts will not interrupt each other. They will be executed according to their priority.