2015-08-04 17 views
10

Ich verwende AVR-GCC 4.9.2, und ich würde gerne wissen, was passiert, wenn ich eine vorzeitige Rückkehr in eine ISR auf einem AVR mache?Was passiert mit einer vorzeitigen "Rückkehr" in einem ISR?

ISR(USART_RXC_vect) 
{ 
    ... 
    if(idx == BUFSIZE) 
     return; 
    ... 
} 

Wird die return zu einem reti Befehl übersetzt werden? Oder muss ich selbst eine reti() einschließen?

Ich bin auf der Suche nach einer detaillierten Erklärung dessen, was hinter den Kulissen passiert.

Antwort

9

Wie
ISR(USART_RXC_vect)
nicht buchstäblich nur
USART_INTERUPT_VECTOR:
in Assembler,

return;
ist nicht buchstäblich nur
ret
oder
reti
in Assembler.

Beide Anweisungen in C/C++ werden in mehrere Assembler-Anweisungen übersetzt, und in beiden Fällen hängt dies vom Kontext ab. Der Kontext für eine ISR(){} ist in diesem Fall ziemlich einspurig, aber es wird höchstwahrscheinlich auch ein paar Pushs enthalten und das SREG speichern. Die Anzahl der Push-Vorgänge zum Stack hängt jedoch davon ab, was in der Funktion passiert.

So wird jeder return; im Zusammenhang interpretiert werden. Am Ende einer normalen Subroutine, die tatsächlich in eine Subroutine eingebaut wird (viele Subroutinen mit begrenzter Verwendung werden von einem Compiler aus Gründen der Code-Effizienz "eingekreist"), wird sie zu einer ret-Anweisung (nach der Behandlung aller benötigten POPs und anderer Low-Level-Befehle). Reinigungsstufe). Am Ende eines Interrupts bedeutet das eigentlich "setze alles, was du vorher gedrückt hast (und auch das SREG wiederherstellst) und dann reti".

Wenn Sie einen Typ zurückgeben, der zur Übertragung dieses Werts durch das Plattformsystem kompiliert wird, bevor Sie die Anweisung ret einfügen. So ist return; eine sehr kontextsensitive Aussage, von der Sie annehmen können, dass sie richtig interpretiert wird, es sei denn, Sie machen sehr seltsame Dinge. Aber diese seltsamen Dinge werden Dinge sein, für die ein guter Compiler (wie AVR-GCC) zumindest warnen wird.

3

Wie gesagt here, vorzeitige return s in der ISR (nicht in seinen untergeordneten Funktionen) sind in reti übersetzt, so ist dies kein Problem.

+0

[Kommentar # 4] (http://www.avrfreaks.net/comment/315442#comment-315442) in den Link, den Sie zur Verfügung gestellt, sagt, dass es "' immer auf die ISR-Funktion Epilog "springen wird, die in turn "säubert alle Ressourcen, die vom ISR verwendet werden, stellt den CPU-Zustand wieder her und endet schließlich in einem ausgeführten RETI". Wenn ja, könnte Ihre Antwort ein wenig irreführend sein. –

+0

@Roflo danke. Ich hatte nach dem zweiten Posten dort aufgehört zu lesen. –