Dosmo schrieb:
> Normalerweise versucht man, ISRs so kurz wie möglich zu halten.
> D.h. eine ISR, die mehr als 10ms Laufzeit hat, hat
> Optimierungspotential.
> In ISR gehören keine Warteschleifen o.ä.
>
> Aber zu Deiner Frage:
> Wenn ein Interruptereignis auftritt, setzt der Prozessor das "Interrupt
> Request"-Flag ("IR"). Falls dann das entsprechende "Interrupt
> Enable"-Flag ("IE") gesetzt ist, wird die ISR angesprungen.
Nitpicking: Und natürlich nur dann, wenn die Interrupts global
freigegeben sind.
Diese globale Freigabe wird bei den AVR mit dem Einsprung in die ISR
sofort automatisch zurückgenommen, womit verhindert wird, dass eine ISR
von einer anderen ISR unterbrochen werden kann (im Normalfall). Mit dem
abschliessenden RETI in der ISR, wird diese Freigabe wieder
eingerichtet. d.h. ab dem RETI ist dann die AUsführung einer anderen ISR
wieder möglich. (ganz genau genommen: erst mit dem übernächsten
Assembler-Befehl)
Das ist nämlich insofern wichtig, als das hier
> Falls beim Verlassen der ISR "IR" und "IE" gesetzt sind, wird die ISR so
> schnell es geht wieder angesprungen. Daher löscht man "IR" normalerweise
> direkt vor dem Aussprung bzw. der Prozessor tut das selbst.
nämlich falsch ist.
Das auslösende "IR" Flag wird vom µC mit dem Einsprung in die ISR
gelöscht und nicht am Ende.
Tritt also während einer ISR derselbe Interrupt erneut auf, dann wird
das dadurch registriert, indem das zugehörige IR Flag erneut gesetzt
wird, so wie sonst auch. Lediglich die Ausführung der ISR wird wegen der
gesperrten globalen Interruptfreigabe solange verhindert, bis die gerade
laufende ISR mittels RETI abgeschlossen wurde.
Konsequenzen
* ein einzeln auftretender Interrupt Request (auch derselben Art)
während einer ISR ist kein Problem. Er wird registriert, geht
nicht verloren und führt nach Beendigung der ISR zu einem ganz
normalen Auslösen der zugehörigen ISR.
* es ist eine extrem schlechte Idee, selber in die globalen Interrupt
Flags einzugreifen, indem man prinzipiell am Anfang einer ISR einen
gut gemeinten cli bzw. am Ende einen sei macht. Das macht der µC
schon selber und er macht es zu Zeitpunkten an denen es nicht mehr
möglich ist, dass sich ISR Aufrufe rekursiv ineinander schachteln,
wenn die Interrupts zu schnell auftreten.
Edit: Alles natürlich auf AVR bezogen. Bei anderen µC (MSP, ARM, ...)
kann das alles ganz anders sein.