我正在使用AVR-GCC 4.9.2,我想知道如果我在AVR上的ISR中过早返回会发生什么?
game.getPostProcessor().enableBlending();
将ISR(USART_RXC_vect)
{
...
if(idx == BUFSIZE)
return;
...
}
转换为return
指令吗?或者我是否需要自己添加reti
?
我正在寻找有关幕后情况的详细解释。
答案 0 :(得分:9)
就像
reti
不是字面上只是
ISR(USART_RXC_vect)
在Assembler中,
USART_INTERUPT_VECTOR:
不是字面上只是
return;
或
ret
在汇编程序中。
C / C ++中的两个指令都将被翻译成多个Assembler语句,在这两种情况下,它都将依赖于上下文。在这种情况下,reti
的上下文非常单一,但它很可能还包括一些推送和存储SREG。但推送到堆栈的次数取决于函数中发生的情况。
所有ISR(){}
都将在上下文中被解释。在一个正常的子程序结束时,它实际上被构建到一个子程序中(许多有限使用的子程序由编译器出于代码效率的原因而被编译器内置")它将成为return;
指令(处理任何需要的持久性有机污染物和其他低级别清理后)。在中断结束时,它实际上意味着弹出之前推送的所有内容(并恢复SREG),然后ret
"。
当您返回一个类型,该类型将被编译为通过平台系统传输该值,然后再包含reti
指令。所以ret
是一个非常上下文敏感的语句,你可以假设它将被正确解释,除非你做了很奇怪的事情。但那些奇怪的事情将是一个好的编译器(如AVR-GCC)至少会警告的事情。
答案 1 :(得分:3)
如上所述here,ISR中的过早reti()
(不在其子函数中)被转换为return
,因此这没有问题。