我正在使用AVR-GCC 4.9.2,我想知道如果我在AVR的ISR上做了过早的回报会发生什么?ISR中的过早“返回”会发生什么?
ISR(USART_RXC_vect)
{
...
if(idx == BUFSIZE)
return;
...
}
请问return
被翻译成一个reti
指令?或者我需要自己添加一个reti()
?
我在寻找关于在幕后发生了什么的详细解释。
我正在使用AVR-GCC 4.9.2,我想知道如果我在AVR的ISR上做了过早的回报会发生什么?ISR中的过早“返回”会发生什么?
ISR(USART_RXC_vect)
{
...
if(idx == BUFSIZE)
return;
...
}
请问return
被翻译成一个reti
指令?或者我需要自己添加一个reti()
?
我在寻找关于在幕后发生了什么的详细解释。
正如
ISR(USART_RXC_vect)
是不是真的只是
USART_INTERUPT_VECTOR:
在汇编 ,
return;
是不是真的只是
ret
或
reti
汇编程序中的。
C/C++中的两条指令都将被翻译成多个汇编语句,并且在这两种情况下都取决于上下文。在这种情况下,ISR(){}
的上下文是相当单一的,但它很可能还包括一些推动和存储SREG。但是推入堆栈的数量将取决于函数中发生的情况。
因此,任何return;
将在上下文中解释。在实际构建到子例程中的正常子例程结束时(为了代码效率的原因,许多限制使用的子例程被编译器“内联”),它将成为ret
指令(在处理任何需要的POP和其他低级别的子程序之后)级清理)。在中断结束时,它实际上意味着“弹出之前推送的所有内容(并恢复SREG),然后执行reti
”。
在包含ret
指令之前,当您返回将通过平台系统传输该值的类型时。所以return;
是一个非常敏感的语句,你可以假设它会被正确解释,除非你做了很奇怪的事情。但那些奇怪的东西将会是一个好的编译器(比如AVR-GCC)至少会提出警告。
如上所述here,在ISR(不在其子功能中)的早期return
被翻译为reti
,所以这没有问题。
[评论#4](http://www.avrfreaks.net/comment/315442#comment-315442)在你提供的链接中表示它会“总是跳转到ISR的函数epilogue'”,它将会转“清理ISR使用的所有资源,恢复CPU状态,最终结束执行RETI”。如果是这样,你的答案可能有点误导。 – 2015-08-04 21:38:25
@Roflo谢谢。在那里的第二篇文章后,我停止阅读。 – 2015-08-04 21:47:19