简体   繁体   English

ARM中断处理程序

[英]ARM Interrupt Handler

First to say that I already read this and could not understand or get a clear answer. 首先要说我已经读过这篇文章 ,无法理解或得到清晰的答案。 I am an AVR guy trying to learn ARM. 我是试图学习ARM的AVR专家。 I am programming the ATSAM4LC2AA from ATMEL. 我正在从ATMEL编程ATSAM4LC2AA。 When I encounter the ISR handler should I disable global interrupts? 遇到ISR处理程序时,应该禁用全局中断吗? And if so is this the correct piece of code? 如果是这样,这是正确的代码吗?

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

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

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

The basic gist of the linked answer is "in the ARM M-profile architecture, you usually don't need to do anything". 链接答案的基本要点是“在ARM M-profile体系结构中,您通常不需要执行任何操作”。 Taking any exception automatically masks any other exceptions of equal or lower priority. 采取任何例外措施会自动掩盖所有其他优先级相同或更低的例外情况。 Returning from the exception handler automatically restores the previous state. 从异常处理程序返回的内容将自动恢复先前的状态。 If you find yourself wanting to mask higher -priority exceptions within a lower-priority handler, start by considering whether you've got your priorities set appropriately in the first place - there are occasional valid reasons for doing so, but if you don't already know why you need to, you don't need to. 如果您发现自己想在较低优先级的处理程序中掩盖较高优先级的异常,请首先考虑是否首先适当设置了优先级-偶尔有这样做的有效理由,但是如果您不这样做,已经知道为什么需要,您不需要。

cpu_irq_save() normally doesn't disable interrupts, it just returns the state of the flags. cpu_irq_save()通常不会禁用中断,它只会返回标志的状态。 The current and all lower priority interrupts have already been disabled. 当前和所有较低优先级的中断已被禁用。 cpu_irq_restore(flags), restores the flags. cpu_irq_restore(flags),恢复标志。 I'm not sure why these calls would be needed unless USARTx_Handler() is changing the state of the flags. 我不确定为什么除非USARTx_Handler()更改标志的状态,否则将需要这些调用。 Usually there is some kernel (operating system) code that has already saved "context" before calling USARTx_Handler(). 通常,在调用USARTx_Handler()之前,已经有一些内核(操作系统)代码已经保存了“上下文”。

If this isn't a nested interrupt, then the ARM changed from thread mode to handler mode to handle the interrupt. 如果这不是嵌套中断,则ARM从线程模式更改为处理程序模式以处理该中断。 The typical kernel (operating system) code outside of USARTx_Handler() that handles the actual interrupt (exception) calls USARTx_Handler(), then when USARTx_Handler(void) returns, it's the kernel code that would restore the ARM to it's prior state, typically back to thread mode (unless it's in a nested interrupt state). 在USARTx_Handler()之外的用于处理实际中断(异常)的典型内核(操作系统)代码将调用USARTx_Handler(),然后在USARTx_Handler(void)返回时,将ARM代码还原到先前状态的是内核代码,通常是进入线程模式(除非处于嵌套中断状态)。

In the case of a multi-threaded kernel (like some version of a RTOS), it may include functions that can be called from an interrupt handler that eventually result in a context switch to a different thread when the interrupt function returns. 对于多线程内核(例如某些版本的RTOS),它可能包含可以从中断处理程序调用的函数,这些函数最终会在中断函数返回时导致上下文切换到其他线程。

update - based on Tedi's comment, cpu_irq_save() is also disabling interrupts (apparently saving the flags before disabling interrupts). 更新 -根据Tedi的评论,cpu_irq_save()也禁用了中断(显然在禁用中断之前保存了标志)。 The function name could have been better, cpu_irq_save_and_disable_irq(), but perhaps too long. 函数名称本来可以更好一些,cpu_irq_save_and_disable_irq(),但是可能太长了。 As long as the documentation shows how these functions are supposed to work, the name isn't that important. 只要文档显示这些功能应该如何工作,名称就不是那么重要。

This creates timing windows, at anytime after USARTx_Handler() is called but before cpu_irq_disable actually disables interrupts, a higher priority interrupt could preempt USARTx_Handler(). 这会在调用USARTx_Handler()之后但在cpu_irq_disable实际上禁止中断之前的任何时间创建计时窗口,优先级较高的中断可能会抢占USARTx_Handler()。 Also, at anytime after interrupts are (assuming here) enabled by cpu_irq_restore(), but before USARTx_Handler() returns, a higher priority interrupt could also preempt USARTx_Handler(). 同样,在cpu_irq_restore()允许中断之后(在这里),但在USARTx_Handler()返回之前的任何时候,优先级较高的中断也可以抢占USARTx_Handler()。 But at least you know between cpu_irq_save() and cpu_irq_restore() that interrupts are disabled. 但是至少您知道在cpu_irq_save()和cpu_irq_restore()之间禁用了中断。

What if you didn't want USARTx_Handler() to disable higher priority interrupts? 如果您不希望USARTx_Handler()禁用更高优先级的中断怎么办? Are there any special calls needed for that? 为此是否有任何特殊要求?

Since I don't know anything about the kernel / RTOS being used here, I'm not sure of the implications of implementing interrupt handlers in this manner. 由于我对此处使用的内核/ RTOS一无所知,因此我不确定以这种方式实现中断处理程序的含义。 One issue is if the kernel supports nested interrupts being able to call kernel functions such as ones that result in a context switch when the interrupt chain returns to thread mode from handler mode. 一个问题是内核是否支持嵌套中断,这些嵌套中断能够调用内核函数,例如当中断链从处理程序模式返回线程模式时导致上下文切换的函数。

There's also the issue of how NMI (non maskable interrupt) is handled. 还有一个问题是如何处理NMI(不可屏蔽中断)。 Some RTOS's don't handle this, so the solution is for an embedded device to set a special hardware based interrupt (IRQ) in the NMI handler, and then just return from the NMI, where the special interrupt handler completes the sequence started by the NMI. 某些RTOS不能处理此问题,因此解决方案是让嵌入式设备在NMI处理程序中设置特殊的基于硬件的中断(IRQ),然后从NMI返回,在此处特殊中断处理程序完成由NMI启动的序列。 NMI。 Other RTOS's can handle system calls from nested IRQ and/or NMI. 其他RTOS可以处理来自嵌套IRQ和/或NMI的系统调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM