ARM 中断处理程序

ARM Interrupt Handler

首先声明我已经阅读了 this 并且无法理解或得到明确的答案。 我是一名尝试学习 ARM 的 AVR 人员。我正在为 ATMEL 的 ATSAM4LC2AA 编程。 当我遇到 ISR 处理程序时,我应该禁用全局中断吗? 如果是这样的话,这是正确的代码吗?

void USARTx_Handler(void)
{
    /* Disable interrupts */
    irqflags_t flags = cpu_irq_save();

    /* Read USART Status. */
    Do_small_task();

    /* Enable interrupts */
    cpu_irq_restore(flags);
}

链接答案的基本要点是"in the ARM M-profile architecture, you usually don't need to do anything"。接受任何异常会自动屏蔽任何其他同等或较低优先级的异常。从异常处理程序返回会自动恢复以前的状态。如果您发现自己想在低优先级处理程序中屏蔽 更高 优先级异常,请首先考虑您是否已正确设置优先级 - 偶尔会有正当理由这样做,但如果你还不知道为什么你需要,你不需要。

cpu_irq_save() 通常不会禁用中断,它只是 return 标志的状态。当前和所有优先级较低的中断已被禁用。 cpu_irq_restore(flags),恢复标志。我不确定为什么需要这些调用,除非 USARTx_Handler() 正在更改标志的状态。通常有一些内核(操作系统)代码在调用 USARTx_Handler() 之前已经保存 "context".

如果这不是嵌套中断,那么ARM从线程模式切换到处理程序模式来处理中断。 USARTx_Handler() 之外处理实际中断(异常)的典型内核(操作系统)代码调用 USARTx_Handler(),然后当 USARTx_Handler(void) returns ,它是将 ARM 恢复到其先前状态的内核代码,通常返回到线程模式(除非它处于嵌套中断状态)。

在多线程内核的情况下(如某些版本的 RTOS),它可能包含可以从中断处理程序调用的函数,当中断函数执行时最终导致上下文切换到不同的线程returns.

update - 根据 Tedi 的评论,cpu_irq_save() 也在禁用中断(显然在禁用中断之前保存标志)。函数名本来可以更好,cpu_irq_save_and_disable_irq(),但可能太长了。只要文档说明了这些函数应该如何工作,名称就没那么重要了。

这会创建计时 windows,在调用 USARTx_Handler() 之后但在 cpu_irq_disable 实际禁用中断之前的任何时间,更高优先级的中断可以抢占 USARTx_Handler() .此外,在 cpu_irq_restore() 启用中断(假设此处)之后的任何时候,但在 USARTx_Handler() returns 之前,更高优先级的中断也可以抢占 USARTx_Handler( ).但至少你知道在 cpu_irq_save() 和 cpu_irq_restore() 之间中断被禁用。

如果您不想 USARTx_Handler() 禁用更高优先级的中断怎么办?是否需要任何特殊调用?

因为我对这里使用的内核/实时操作系统一无所知,所以我不确定以这种方式实现中断处理程序的含义。一个问题是内核是否支持能够调用内核函数的嵌套中断,例如当中断链 return 从处理程序模式到线程模式时导致上下文切换的函数。

还有如何处理 NMI(不可屏蔽中断)的问题。一些 RTOS 不处理这个,所以解决方案是让嵌入式设备在 NMI 处理程序中设置一个特殊的基于硬件的中断 (IRQ),然后从 NMI 中 return,特殊的中断处理程序完成由 NMI 启动的序列。其他 RTOS 可以处理来自嵌套 IRQ and/or NMI.

的系统调用