ARM中断处理程序

时间:2016-10-31 23:58:14

标签: c arm isr

首先要说我已经阅读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);
}

2 个答案:

答案 0 :(得分:2)

链接答案的基本要点是“在ARM M-profile架构中,您通常不需要做任何事情”。任何异常都会自动屏蔽任何其他具有相同或更低优先级的异常。从异常处理程序返回会自动恢复以前的状态。如果您发现自己想要在优先级较低的处理程序中屏蔽更高 - 优先级异常,那么首先要考虑您是否首先正确设置了优先级 - 偶尔有正当理由这样做,但如果您还不知道为什么需要,则不需要。

答案 1 :(得分:1)

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

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

对于多线程内核(如某些版本的RTOS),它可能包含可以从中断处理程序调用的函数,这些函数最终会在中断函数返回时导致上下文切换到不同的线程。

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

这会创建时序窗口,在调用USARTx_Handler()之后的任何时间但在cpu_irq_disable实际禁用中断之前,优先级较高的中断可以抢占USARTx_Handler()。此外,在cpu_irq_restore()启用中断(假设此处)之后的任何时间,但在USARTx_Handler()返回之前,更高优先级的中断也可以抢占USARTx_Handler()。但至少你知道cpu_irq_save()和cpu_irq_restore()之间是否禁用了中断。

如果您不希望USARTx_Handler()禁用更高优先级的中断,该怎么办?是否需要特殊电话?

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

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