C++ 如果ISR运行时发生中断,会发生什么情况?

C++ 如果ISR运行时发生中断,会发生什么情况?,c++,c,arduino,interrupt,C++,C,Arduino,Interrupt,我正在编程arduino,我在pin2下降沿上附加了一个中断。当我在ISR时,ISR并没有执行所有的命令。在完成所有线路之前,如果下降边缘再次出现,会发生什么?中断是从开始还是忽略它。这里我只讨论pin2上的中断。当发生中断时,Atmel处理器禁用中断: (第4.4节:位7–I:全局中断启用) 必须设置全局中断启用位,才能启用中断 启用。然后执行单独的中断启用控制 在单独的控制寄存器中。如果全局中断启用寄存器 如果清除,则所有中断都不会独立于 单个中断启用设置。I位由硬件清除 中断发生后,由RE

我正在编程arduino,我在pin2下降沿上附加了一个中断。当我在ISR时,ISR并没有执行所有的命令。在完成所有线路之前,如果下降边缘再次出现,会发生什么?中断是从开始还是忽略它。这里我只讨论pin2上的中断。

当发生中断时,Atmel处理器禁用中断:

(第4.4节:位7–I:全局中断启用)

必须设置全局中断启用位,才能启用中断 启用。然后执行单独的中断启用控制 在单独的控制寄存器中。如果全局中断启用寄存器 如果清除,则所有中断都不会独立于 单个中断启用设置。I位由硬件清除 中断发生后,由RETI指令设置为 启用后续中断。I位也可以通过设置和清除 应用程序包含SEI和CLI指令,如中所述 指令集参考

进一步:

外部中断标志寄存器–EIFR

•位7..0–INTF6、INTF3-INTF0:外部中断标志6、3-0 当INT[6;3:0]引脚上的边缘或逻辑更改触发 中断请求,INTF7:0变为设置(一)。如果SREG中的I位和 设置EIMSK中相应的中断启用位INT[6;3:0] (一),MCU将跳转到中断向量。旗帜被清除了 当中断程序被执行时。或者,该标志可以是 通过向其写入逻辑1来清除。这些旗帜总是被清除的 当INT[6;3:0]被配置为电平中断时。注意,当 在INT3:0中断被禁用的情况下进入睡眠模式,输入 这些引脚上的缓冲区将被禁用。这可能会导致逻辑变化 在将设置INTF3:0标志的内部信号中

换句话说,当检测到另一个中断时,标志寄存器将设置该位,并在中断再次启用时(如果未采取单独的操作,则在中断返回时)执行该中断

如果您愿意,您可以实现在中断服务例程期间启用中断的代码,但您必须确保该点之后的代码完全可重入,和/或屏蔽当前中断(一些中断服务例程在不久之后没有收到另一个中断时非常难以处理,如果当前在处理程序中收到另一个中断,则几乎不可能处理)。然而,通常情况下,正确的操作系统会启用所有其他中断,这意味着写入EIMSK寄存器

一般来说,最好只在中断处理程序中收集必要的信息,将其存储在“安全”的地方(循环缓冲区对这一点很好),并向系统中的常规任务发出新数据可用的信号,然后在那里处理数据


[此外,据我所知,在中断内没有任何东西可以阻止函数调用-只要您了解自己在做什么,并且没有任何问题,例如从中断和常规代码同时调用函数]

我不知道Arduino的具体情况,但许多小型CPU在另一个中断进行时禁用中断。这是使ISR尽可能短的一个重要原因。许多其他CPU具有不同优先级的中断,因此优先级较高的中断可以中断优先级较低的中断。您应该阅读Arduino板上CPU的规格。一般来说,保持ISR尽可能小和短,一个好的ISR可能只是设置一个主回路将检查的标志。我的传感器去抖动,因此始终不能仅依赖于中断。必须在中断内完成计算,以使去抖动不受影响。我可以通过校准l中断功能?处理ISR内的去抖动按钮绝对是不应该做的事情。不管怎样,在ISR外的代码中处理都很容易(只需忽略特定时间段内的多次按钮按下)。是的,您可以从ISR内部调用函数,但应小心不要调用任何可能导致进一步中断的函数,因为这可能会导致死锁。+1,我可以确认在中断处理程序中调用函数没有问题。正如@Mats所说,如果可以从mult重新输入从函数访问的非本地数据,则可能会出现问题iple、嵌套中断或来自中断和用户状态的中断,例如,可以安全调用的操作系统功能集非常小。