Der AVR-SEI-Befehl ( http://www.atmel.com/webdoc/avrassembler/avrassembler.wb_SEI.html ) wartet auf den Abschluss des nächsten Befehls, bevor Interrupts aktiviert werden.
Wenn ich einen anderen Befehl verwende, um das I-Flag in SREG zu setzen, wartet dieser auch 1 Befehl?
Mit anderen Worten: Ist das Warten ein Merkmal des SEI-Befehls oder des Statusregisters?
Wenn es sich um ein Merkmal des SEI-Befehls handelt, wann wird das Flag tatsächlich gesetzt, in dem Zyklus, in dem der SEI ausgeführt wird, oder mit dem nächsten Befehl?
avr
interrupts
assembly
Jayjay
quelle
quelle
Antworten:
Empirische Ergebnisse!
Während die anderen Antworten nachdenklich und gut begründet sind, sind sie alle unvollständig oder nur Vermutungen. Wenn die Dokumentation nicht eindeutig ist, müssen wir experimentieren und jeden Fall testen.
Diese Frage verdient eine abschließende Antwort, also lasst uns einen AVR herausziehen und ein paar Bits setzen!
Verfahren
Zum Testen habe ich ein kleines Arduino (ATMEGA328P) -Programm erstellt, das ...
while (1)
)INT0
wird niedrig)Ich habe einen Prüfstand verwendet, der in der Einzelanweisung eine LED einschaltet, nachdem Interrupts aktiviert wurden. Durch Ausprobieren verschiedener Möglichkeiten zum Aktivieren von Interrupts im Prüfstand und Überprüfen der LED konnte ich feststellen, ob der Befehl nach dem Freigabebefehl ausgeführt wurde oder nicht.
Wenn die LED nicht aufleuchtet, weiß ich, dass der ISR sofort ausgeführt (und gesperrt) wurde, nachdem Interrupts aktiviert wurden.
Wenn die LED aufleuchtet, weiß ich, dass der nächste Befehl ausgeführt werden durfte, bevor der ISR aufgerufen wurde.
Ergebnisse
SEI
Anweisung (Basisfall)Code:
sei
Ergebnis: LED an. Folgeanweisung ausgeführt.
OUT
AnweisungCode:
Ergebnis:
LED leuchtet. Folgeanweisung ausgeführt.
ST
AnweisungCode:
Ergebnis:
LED leuchtet. Folgeanweisung ausgeführt.
Fazit!
F: Ist das Warten ein Merkmal des SEI-Befehls oder des Statusregisters?
A: Es sieht so aus, als würde das
I
Bit inSREG
von a0
nach a geändert1
die nächste Ausführung des folgenden Befehls ermöglicht, selbst wenn ein Interrupt ansteht, unabhängig davon, welcher Befehl zum Setzen des Bits verwendet wird.Anmerkungen
Dies wurde tatsächlich zu einer sehr interessanten Frage mit vielen Komplikationen. Wenn Sie sich für die Details interessieren, lesen Sie ...
http://wp.josh.com/2016/01/05/different-ways-to-set-i-bit-in-avr-sreg-besides-sei/
quelle
Nach meinem Verständnis aus der Dokumentation unterscheidet sich das Ausführen des
sei
Befehls nicht vom direkten Schreiben einer 1 in das I-Bit des SREG. Der Vorteil des Befehls besteht darin, dass Sie nicht erst einen Wert von1<<I
in ein Arbeitsregister laden müssen, um das SREG zu ändern, wodurch Zeit gespart wird.Zum Ausarbeiten verwenden Sie
sei
:Setzen des Bits mit
sbi
(würde nur funktionieren, wenn sich SREG in den unteren 32 Bytes der Registerkarte befindet, aber es scheint, dass dies auf den meisten, wenn nicht allen nicht der Fall ist.)Schreiben an mich direkt in SREG:
Das
I
Bit sollte in SREG gesetzt werden, sobald dersei
Befehl (odersbi
oderout
) abgeschlossen ist. Anstehende Interrupts werden jedoch erst nach Abschluss des nächsten Befehls behandelt - das Bit wird gesetzt, aber es dauert einen zusätzlichen Zyklus, bis die Interrupts aktiviert werden. Da ein Interrupt während der Ausführung eines Befehls nicht verarbeitet werden kann und einige Befehle mehr als einen Zyklus benötigen, geben sie die Zeit an, die erforderlich ist, um als ein Befehl aktiviert zu werden. Dies sollte für alle Versionen des Codes der Fall sein - dh, jede der oben genannten Situationen führt zu einer Verzögerung einer Anweisung.Nach einigem Suchen fand ich diesen Thread im Arduino-Forum, in dem verschiedene Tests durchgeführt wurden, um das Verhalten zu überprüfen. Es scheint mit dem übereinzustimmen, was ich oben gesagt habe.
Wenn gemäß diesem Thread das
I
Flag bereits gesetzt ist, gibt es keine verzögerte Antwort eines Interrupts,sei
was impliziert, dass die verzögerte Antwort nicht durch den Befehl selbst verursacht wird, sondern durch die interne Hardware, die durch dasI
Flag gesteuert wird. so jede Operation , die die Flagge in SREG ändert, sei essei
oderout
odersts
haben genau das gleiche Verhalten.quelle
SBI
nicht verwendet werden kann, um dasI
BitSREG
so einzustellen, dass ein Code, der dies wahrscheinlich tut, nicht im wirklichen Leben getestet wurde, da er nicht einmal zusammengesetzt werden kann.SBI
kann nur mit den unteren 32 Registern arbeiten und SREG befindet sich aufout
war dasjenige, das ich ursprünglich verwendet habe. Ich dachte, ich stoße auf einen AVR (könnte ein ATTiny sein), der die SREG in den unteren 32 Registern hat, aber ich kann es mir vorstellen.IMHO schreibt an SREG noch Verzögerung 1 Anweisung kann wie folgt getestet werden (Pseudocode):
Leider fehlt mir die Zeit dafür :(
quelle
So steht es nicht. In den Dokumentationen heißt es
nicht, dass es auf die nächste Anweisung wartet. Ich habe dies gelesen, da das Flag sofort gesetzt ist, aber obwohl es aktiviert ist, werden keine Interrupts behandelt, bis der nächste Befehl ausgeführt wurde.
quelle