>was ist denn wenn der interupt kommtn wärend ich noch im handler bin?
Der gleiche Interrupt A sollte selbstverständlich niemals auftreten,
während das Programm noch im Interrupthandler von A verweilt. Das würde
das Konzept der Interrupts zunichte machen (Erklärungen dazu weiter
unten). Es gilt ja die Regel, dass alle Interrupthandler so kurz wie
möglich zu halten sind, damit der µC immer genug Luft hat, alle
auftretenden Interrupts abzuarbeiten.
Was man natürlich nicht verhindern kann, ist das Auftreten einer
Interruptbedingung B, während sich das Programm gerade im
A-Interrupthandler aufhält. Viele Interrupts werden schließlich von
externen Ereignissen ausgelöst, und wenn Du z. B. ein Zeichen von Deinem
PC über die serielle Schnittstelle abschickst, weißt Du nicht, womit
Dein Programm in dem Moment beschäftigt ist, in dem die
UARTDataRxComplete-Interruptbedingung zutrifft.
Dann passiert folgendes. Grundsätzlich wird beim Auftreten einer
Interruptbedingung immer augenblicklich das zugehörige Interrupt-Flag
von der Interruptlogik gesetzt. Diese Flags stecken in den
I/O-Registern Deines Controllers (z. B. ICF1, TOV1, RXC, TXC, ACI).
Damit ist der Interrupt "vorgemerkt" (engl. pending interrupt). Wann
jedoch der Sprung auf den Interruptvektor (und von dort aus in den
Interrupthandler) erfolgt, hängt vom I-Flag im SREG (globales
Interrupt-Freigabeflag) ab. Solange es gelöscht (alle Interrupts
gesperrt) ist, erfolgt kein Sprung - der Interrupt bleibt vorgemerkt.
Ist es gesetzt, wird in jedem Fall noch die gerade ausgeführte
Instruktion zuende verarbeitet, und dann erfolgt der Sprung auf den
Interruptvektor. Mit diesem Sprung wird automatisch gleichzeitig das
spezifische Interruptflag gelöscht (*) und ebenso das I-Flag.
Interrupthandlers können also nicht durch andere Interrupts
geinterrupted werden (außer Du setzt das I-Flag am Anfang des Handlers
durch ein "sei" - das solltest Du aber wegen des Risikos eines
Stacküberlaufs niemals tun). Das Wieder-Setzen des I-Flags geschieht i.
a. mit dem "reti" am Ende eines Interruptshandlers, wobei dies dem
Programmierer obliegt.
(*) Meistens, aber es gibt spezielle Fälle, wo es anders geregelt ist.
Das I-Flag kann man auch selbst löschen und wieder setzten (mit "cli"
und "sei"), wenn man möchte, dass bestimmte kritische Programmabschnitte
aus irgendeinem Grund nicht von einem Interrupt unterbrochen werden. Das
nennt man eine Critical Section. Auch solche Abschnitte sollten
möglichst kurz gehalten werden.
Und klar, es kann sogar sein, dass im Moment des Wieder-Setzens des
I-Flags zufällig mehrere Interrupts anstehen. Dann wird derjenige
davon ausgeführt, der am weitesten "oben" in der Interruptvektor-Tabelle
steht, während die anderen natürlich pending bleiben. Das ist dann so
eine Art Interrupt-Priorität (aber keine "echte" wie bei anderen
Controllerfamilien).
Bei lange dauernden Interrupts würde man Gefahr laufen, Interrupts zu
"verlieren". Das wäre dann der Fall, wenn ein Interruptflag gesetzt
würde, welches schon gesetzt ist. Hält man dagegen alle
Interrupthandler und alle critical sections wie gesagt kurz, kann das
nicht passieren, weil alle Pending-Flags schnell wieder gelöscht werden.
Man kann diesen Mechanismus übrigens auch im Simulator vom AVRStudio in
allen Einzelheiten nachverfolgen. Gegebenenfalls viel Spaß ;-)