mikrocontroller.net

Forum: Compiler & IDEs SREG innerhalb ISR speichern?


Autor: Tommy M. (muello)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Tommy M. (muello)
Datum:

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

Tommy

Autor: Rahul, der Trollige (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Rahul, der Trollige (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Tommy M. (muello)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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


Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rahul, der Trollige (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zickenterror?

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schlammcatchen...

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: johnny.m (Gast)
Datum:

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

Autor: AVRFan (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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).

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.)

Autor: AVRFan (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...;-)

Autor: AVRFan (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 :-)

Autor: Werner B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
<alt><Ziffernblock->105

Autor: Rahul, der Trollige (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
><alt><Ziffernblock->105
*lol

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.