www.mikrocontroller.net

Forum: Compiler & IDEs interrupts deaktivieren


Autor: schnudl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
im avr-libc user manual wird folgende vorgangsweise für das aus- und 
wiedereinschalten des globalen Interruptflags empfohlen:

uint8_t tmp_sreg = SREG;
// ??
cli();
...
SREG = tmp_sreg;

Soweit klar, nur was passiert, wenn ein anderer Interrupt genau an der 
mit ?? bezeichneten Stelle zuschlägt ? Der kann dann SREG verändern, und 
das Programm könnte dadurch durcheinanderkommen, da der unter tmp_sreg 
gespeicherte Wert u.U nicht mehr aktuell ist. Oder sehe ich das falsch ?

Falls das stimmt, wie kann man dieses Problem umgehen ?


--
Danke
Michael

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann wird der Vordergrund an genau der Stelle unterbrochen. Da die ISR 
das SREG speichern und wiederherstellen muß, passiert nichts.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im SREG interessiert an der Stelle ausschließlich das I-Bit. Wenn das 
vorher schon gelöscht war, dann kann gar kein Interrupt dazwischenhauen. 
Wenn es gesetzt war, dann wird es auch hinterher wieder gesetzt, auch 
wenn ein Interrupt dazwischenkommt.

Autor: schnudl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Antworten - Schon klar. Mir ist es um den 
unwahrscheinlichen Fall gegangen, dass die ISR dass I Flag löscht und 
somit Interrupts ausschaltet - oder ist das "nicht erlaubt" ? Könnte ja 
sein, dass dieses I Flag dann im Hauptthread wieder gesetzt wird, 
nachdem einige Dinge abgearbeitet worden sind. Ich selbst würde das zwar 
nicht so machen, aber in einem solchen Fall wäre das Löschen des Bits 
jedenfalls verschwunden.

Die Frage geht auch darauf hinaus, ob es möglich ist, zusammengehörende 
Programmbereiche ununterbrechbar zu machen. Woanders kenne ich zB. ein 
"atomic" Schlüsselwort.

Autor: schnudl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und da gleich nochwas:

Kann man sich darauf verlassen, dass zB eine Zuweisung von Werten an 
variablen mit mehr als 1 Byte (zB long) nicht "zerrissen" werden kann? 
Oder wäre dies denkbar ? Denn es stecken ja mehrere Maschinenbefehle 
dahinter. Dann müsste man wieder mit dem I-Bit arbeiten, wenn man es 
vermeiden möchte?

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
schnudl wrote:
> Danke für die Antworten - Schon klar. Mir ist es um den
> unwahrscheinlichen Fall gegangen, dass die ISR dass I Flag löscht und
> somit Interrupts ausschaltet - oder ist das "nicht erlaubt" ?

Erlaubt schon, allerding kein guter Programmierstil.
In der Regel macht man sowas nur, wenn man vorher die Aufgabe nicht 
durchdacht hat. Wenn ein Interrupt schon was sperren muß, dann nur 
einzelne Interrupts, aber nicht global.


Ich setze mir allerdings das Ziel, daß ich nicht über längere 
Funktionsaufrufe Interrupts sperre und auch Funktionen nicht 
gleichzeitig im Main und in Interrupts aufrufe.
Dann kann man sich das Sichern des SREG sparen und schreibt direkt 
CLI+SEI um den atomaren Ausdruck.

Du kannst Dir ja Macros schreiben:
#define atomic cli();
#define end_atomic sei();


Peter

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ schnudl (Gast)

>unwahrscheinlichen Fall gegangen, dass die ISR dass I Flag löscht und

Eine ISR löscht beim AVR IMMER das I-Bit. Und am Ende wird es immer mit 
RETI wieder gesetzt.

>somit Interrupts ausschaltet - oder ist das "nicht erlaubt" ? Könnte ja

Dasist SEHR unüblich. Interruptsrutinen setzen/löschen bestenfalls die 
inidividuellen Maskenbits für Timer, UARt etc., aber so gut wie nie das 
I-Bit der CPU.

>Die Frage geht auch darauf hinaus, ob es möglich ist, zusammengehörende
>Programmbereiche ununterbrechbar zu machen. Woanders kenne ich zB. ein
>"atomic" Schlüsselwort.

Eben mit der gezeigten Abfolge werden deine Befehle atomar. NAch dem 
cli() spuckt dir keiner mehr dazwischen.

Interrupt

MFg
Falk

Autor: schnudl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
alles klar. danke

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.