FIFO mit Interruptsperre

Gast #2630535
Hallo Forumsgemeinde!

Ich bin gerade dabei mich mit folgendem Artikel auseinanderzusetzen:

http://www.rn-wissen.de/index.php/FIFO_mit_avr-gcc

In beiden Inline-Funktionen im Header ist mir nicht ganz klar warum 
ausgerechnet über

f->count++;

bzw.

f->count--;

eine Interruptsperre ist.

Besten Dank für eine Antwort!
Gast #2630581
Stefan Ernst schrieb:
> Weil das ein RMW-Zugriff ist, der an beiden Enden des FIFOs stattfindet,
> und in der Regel ein Ende des FIFOs per Interrupt bedient wird.

Heißt das soviel, dass die beiden Operationen nicht atomar ausgeführt 
werden?

Müssten eig die kompletten Funktionen in einer Interruptsperre sein?
Da hier ja soweit ich seh sämtliche Zeiger der Reihe nach verändert 
werden, und wenn dazwischen ein Interrupt mit einem FIFO-Zugriff 
ausgelöst wird die neu aufgerufene Funktion falsche Zeigerwerte 
übergeben bekommen würde.
#2630600
Unwissender schrieb:

> Müssten eig die kompletten Funktionen in einer Interruptsperre sein?
> Da hier ja soweit ich seh sämtliche Zeiger der Reihe nach verändert
> werden, und wenn dazwischen ein Interrupt mit einem FIFO-Zugriff
> ausgelöst wird die neu aufgerufene Funktion falsche Zeigerwerte
> übergeben bekommen würde.

Es sind aber nicht dieselben Werte in der put und in der get Funktion. 
Erst durch die Manipulation von count wird die Operation, man könnte 
sagen, gültig. Und da darf der jeweilige Gegenpart nicht 
dazwischenkommen.
Gast #2630897
Eine Frage hätt ich noch.
Warum wird hier das komplette SREG-Register immer gerettet?
Es wurde hier doch nur das I-Flag verändert und nichts weiter.
Wäre nur ein sei() hier nicht einfacher?
#2630941
Unwissender schrieb:
> Eine Frage hätt ich noch.
> Warum wird hier das komplette SREG-Register immer gerettet?
> Es wurde hier doch nur das I-Flag verändert und nichts weiter.
> Wäre nur ein sei() hier nicht einfacher?

Weil du in der Funktion nicht weißt, ob nicht vom Aufrufer die 
Interrupts mittelse sei() bereits gesperrt wurden. Und der hätte was 
dagegen, wenn die Funktion die Interrupts einfach freigeben würde.
Detto, wenn die Funktion aus einer ISR heraus aufgerufen wird.

Daher: Interrupts nicht einfach: sperren und freigeben
sondern   sperren und den vorhergehenden Zustand wieder herstellen.
#2631006
Karl Heinz Buchegger schrieb:
> Weil du in der Funktion nicht weißt, ob nicht vom Aufrufer die
> Interrupts mittelse sei() bereits gesperrt wurden.

In der Regel weiß man es aber.
Da in Interrupts kein Atomic nötig ist.
Und da nach dem Init Interrupts immer enabled sind.

Wenn man also nicht irgendwelche ganz speziellen Schweinereien vorhat, 
ist ein cli/sei vollkommen ausreichend.

Im AVR-GCC entspricht das dem:
1
ATOMIC_BLOCK(ATOMIC_FORCEON){
2
// atomic code
3
}


Peter
#2631194
Peter Dannegger schrieb:

> In der Regel weiß man es aber.

Peter.
Der verlinkte Code ist eine allgemeine FIFO.
Einsatzort: unbekannt. Kann daher sowohl innerhalb als auch ausserhalb 
einer ISR benutzt werden sowie in Funktionen die selbst aus irgendeinem 
Grund unter Interruptsperre laufen.
Und für diese Fälle hat der Programmierer vorgesorgt. Getreu dem Motto: 
Lieber ein wenig langsamer und dafür richtig als schnell und falsch.
Einer Sichtweise, der ich für allgemein verwendbaren Module, die in 
einem Common-Lib Verzeichnis liegen, durchaus etwas abgewinnen kann.
#2635605
Adib T. schrieb:
> Man könnte speziell für den Fall des Aufrufes aus ISR ein
> interruptoptimierte Routine schreiben.

Man könnte nicht nur, man sollte auch.
Man muß ja auch den Sendeinterrupt freigen. Und ist der Sendepuffer 
voll, muß man warten.
Und man hat beim Empfang 3 Byte mehr Puffer, ehe es zu einem Überlauf 
kommt. Dazu muß man nur den Empfangsinterrupt sperren, wenn der 
SW-Puffer voll ist. Einen wirklichen Überlauf kann man dann mit dem 
UART-Flag abtesten.


Peter

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.