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
Dann wird der Vordergrund an genau der Stelle unterbrochen. Da die ISR das SREG speichern und wiederherstellen muß, passiert nichts.
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.
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.
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?
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:
1 | #define atomic cli();
|
2 | #define end_atomic sei();
|
Peter
@ 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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.