Forum: Compiler & IDEs SREG innerhalb ISR speichern?


von Tommy M. (muello)


Lesenswert?

Hallo,

ich habe mich gerade im AVR-GCC-Tutorial den Abschnitt gelesen, wie man 
Codesequenzen schreibt, welche via Interrupt nicht unterbrochen werden 
können.

Macht es Sinn, diesen Ansatz auch innerhalb von ISR zu nutzen?

//timer 2 overflow
SIGNAL(SIG_OVERFLOW2)
{
  uint8_t tmp_sreg = SREG;
  cli();

  TCNT2 = 0xE0;
  //mach irgendwas...

  SREG = tmp_sreg;
}

Viele Grüße
Tommy

von Peter D. (peda)


Lesenswert?

Tommy Müller wrote:

> Macht es Sinn, diesen Ansatz auch innerhalb von ISR zu nutzen?

Nein, laß alles weg.

Der AVR hat keine Interruptprioritäten und damit sind Interrupts immer 
schon atomar.


Peter

von Tommy M. (muello)


Lesenswert?

Was macht der AVR, wenn er gerade eine ISR abarbeitet und ein neuer 
Interrupt "einläuft"? Gibt es dann so eine "Stack"?

Tommy

von Rahul, der Trollige (Gast)


Lesenswert?

>Was macht der AVR, wenn er gerade eine ISR abarbeitet und ein neuer
>Interrupt "einläuft"? Gibt es dann so eine "Stack"?

Er legt sich hin und stellt sich tot!

von Rahul, der Trollige (Gast)


Lesenswert?

Ernsthaft:
Er arbeitet die ISR zuende ab, springt dahin zurück, wo er herkam, gibt 
wieder alle Interrupts frei und stellt fest, dass da ein freigegebener 
Interrupt aufgetreten ist. Und springt in dessen ISR.

AVR haben keine Interrupt-Prioritäten wie sie z.B. die 8051er haben.

von johnny.m (Gast)


Lesenswert?

Wenn eine ISR verlassen wird und in der Zwischenzeit (also während die 
ISR ausgeführt wurde) andere Interrupts aufgetreten sind, werden diese 
nach dem Rücksprung ins Hauptprogramm in der Reihenfolge abgearbeitet, 
wie sie in der Vektortabelle stehen (je niedriger die Vektoradresse, 
desto höher die "Pseudo-Priorität". "Pseudo" deshalb, weil es keine 
"echte" Priorität im Sinne von "höhere Priorität unterbricht niedrigere 
Priorität" ist, sondern lediglich eine Abarbeitungsreihenfolge). Es kann 
natürlich dadurch passieren, dass ein Interrupt mit niedriger Adresse so 
oft auftritt, dass nur noch dieser bearbeitet wird, aber das ist dann 
ein Fehler des Programmierers...

Außerdem wird beim Einsprung in eine ISR automatisch durch die Hardware 
des Controllers das I-Bit im SREG gelöscht, so dass man das nicht von 
Hand machen muss. Es wird erst beim Verlassen der ISR wieder gesetzt 
(auch automatisch durch die Hardware). Deshalb ist ein cli() am Anfang 
der ISR überflüssig.

von Tommy M. (muello)


Lesenswert?

Vielen Dank für eure Antworten ... ich finde es immer schön, wenn die 
Artikel durch "trollige" Postings etwas aufgelockert werden ;-)

Grüße Tommy

von Peter D. (peda)


Lesenswert?

Mit Ausnahme des alten AT90S1200 hat bei den AVRs jede Interruptquelle 
ein Pending-Flag. Damit merkt sich der AVR, daß noch ein Interrupt 
anhängig ist und versucht ihn sobald wie möglich auszuführen.

Alternativ kann man dieses Pending-Flag auch pollen und löschen, wenn 
man das Ereignis ohne Interrupt behandeln will.

Auch kann es sein, daß man nach Verlassen des Interrupts oder längerer 
Interruptsperre garnicht mehr an älteren Ereignissen interessiert ist, 
dann löscht man das Pending-Bit unmittelbar vor dem RETI bzw. SEI.

Und daß man Pending Bits beim AVR nicht mit 0 löschen kann, weiß ja 
jeder.


Peter


von Falk (Gast)


Lesenswert?

@johnny.m

>(auch automatisch durch die Hardware). Deshalb ist ein cli() am Anfang
>der ISR überflüssig.

Um die Restaurierung des SREG braucht man sich in ISR und C doch sowieso 
keine Gedanken zu machen, das macht der Compiler doch automatisch.

MFG
Falk

von johnny.m (Gast)


Lesenswert?

@Falk:
Habe ich mit irgendeinem Wort die SREG-Restaurierung erwähnt? Es ging 
mir nur darum, dass das cli() und sei() durch die Controller-Hardware 
erledigt wird und deshalb im Programm überflüssig ist. Der Controller 
sorgt ganz alleine (und zwar völlig unabhängig von der Art der 
Programmierung) dafür, dass ISRs ohne weiteren Eingriff des 
Programmierers nicht unterbrochen werden können. Das SREG-sichern und 
zurückschreiben ist eine ganz andere Sache.

von Rahul, der Trollige (Gast)


Lesenswert?

Zickenterror?

von Matthias (Gast)


Lesenswert?

Schlammcatchen...

von Falk (Gast)


Lesenswert?

@johnny.m

>Habe ich mit irgendeinem Wort die SREG-Restaurierung erwähnt? Es ging

Locker bleiben ;-)

Mein Kommentar bezog sich im wesentlichen als Ergänzung auf die 
Ursprungsfrage.

MfG
Falk

von johnny.m (Gast)


Lesenswert?

@Falk:
Wenn Du Dich angegriffen gefühlt hast: War keine Absicht. Ehrlich.

von AVRFan (Gast)


Lesenswert?

>Außerdem wird beim Einsprung in eine ISR automatisch durch die Hardware
>des Controllers das I-Bit im SREG gelöscht, so dass man das nicht von
>Hand machen muss.

Richtig.

>Es wird erst beim Verlassen der ISR wieder gesetzt
>(auch automatisch durch die Hardware).

Kleine Korrektur: Nicht automatisch.  Das I-Flag wird durch die 
"reti"-Instruktion genau im Moment (!) des Rücksprungs wieder gesetzt. 
Schreibt der Programmierer fälschlicherweise (oder auch absichtlich) nur 
ein "ret", so bleibt das I-Flag gelöscht, und alle Interrupts auch nach 
Verlassen des Interruptshandlers gesperrt.

von johnny.m (Gast)


Lesenswert?

@AVRFan:
Eine ISR dauert grundsätzlich so lange, bis ein "reti" auftaucht, egal 
was sonst noch an programmiertechnischem Wahnsinn getrieben wird. Wenn 
kein "reti" da ist, obwohl da eins sein sollte, dann hat der 
Programmierer großen Mist gebaut. Das läuft dann unter "grober 
Programmfehler". Ich meinte oben natürlich "beim ordnungsgemäßen 
Verlassen der ISR" (hätte ich vll. direkt dazuschreiben sollen...). Und 
dabei macht die Hardware dann auch das, was sie soll. Solche Sachen 
nimmt einem aber tatsächlich der Compiler ab (genau wie das 
SREG-Sichern).

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Peter Dannegger wrote:

> Mit Ausnahme des alten AT90S1200 hat bei den AVRs jede Interruptquelle
> ein Pending-Flag. Damit merkt sich der AVR, daß noch ein Interrupt
> anhängig ist und versucht ihn sobald wie möglich auszuführen.

Eine Einschränkung: pegelgesteuerte Externinterrupts bleiben nur
so lange anhängig, wie der entsprechende Pegel tatsächlich anliegt.
Verschwindet er also wieder, während die Interruptbearbeitung
gerade gesperrt ist, dann wird danach die zugehörige ISR nicht
abgearbeitet.  (War zumindest bis ATmega16...128 noch so, aktuell
habe ich da lange nicht mehr das Kleingedruckte im Datenblatt
gelesen.)

von AVRFan (Gast)


Lesenswert?

>Eine ISR dauert grundsätzlich so lange, bis ein "reti" auftaucht, egal
>was sonst noch an programmiertechnischem Wahnsinn getrieben wird.

Ein "ret" beendet eine ISR gleichermaßen. Auch dann kehrt das Programm 
schließlich an die Stelle zurück, wo der Interrupt aufgetreten ist, und 
macht mit der nächsten Instruktion dort weiter. Lediglich das I-Flag 
bliebe bei "ret" gelöscht - so what?  Ich könnte mir sogar 
Anwendungsfälle vorstellen, in denen das gewünscht ist (Beispiel: ein 
externer Interrupt soll nur genau einmal ausgelöst werden können). Dann 
spräche nicht das Geringste dagegen, ans Ende der entsprechenden ISR 
tatsächlich ein "ret" statt eines "reti" zu schreiben.

>Solche Sachen nimmt einem aber tatsächlich der Compiler ab (genau wie das
>SREG-Sichern).

Sofern man mit einem solchen arbeitet. Aber bitte keine 
Grundsatzdiskussion über Vor- und Nachteile von 
Assemblern/Compilern/Whatever jetzt... lach

von johnny.m (Gast)


Lesenswert?

@AVRFan:
Naja, da kann man jetzt tatsächlich endlos drüber diskutieren... Fest 
steht: Wenn man eine ISR mit einem ret beendet anstatt mit reti, dann 
sollte man schon ganz genau wissen, was man da tut. Oder die "i"-Taste 
ist kaputt...;-)

von AVRFan (Gast)


Lesenswert?

>Wenn man eine ISR mit einem ret beendet anstatt mit reti, dann
>sollte man schon ganz genau wissen, was man da tut. Oder die "i"-Taste
>ist kaputt...;-)

Da gebe ich Dir allerdings recht :-)

von Werner B. (Gast)


Lesenswert?

<alt><Ziffernblock->105

von Rahul, der Trollige (Gast)


Lesenswert?

><alt><Ziffernblock->105
*lol

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.