PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Bit-Variablen Atomar?



Dunuin
26.06.2011, 09:44
Moin,

Ich nutze gerade den Timer1 per Overflow zum Hochzählen von ein paar Zeitvariablen und den Timer0 per Overflow zum Empfangen von RC5.
In der Hauptschleife halte ich dann kurz alle Interrupts an, damit die Variablen der ISRs nicht verändert werden, während ich diese auslese und es dann nicht zu Fehlern kommt. Wenn ich an das Ende meiner Hauptschleife ein "Waitms 100" setze, dann klappt auch alles prima, mit "waitms 1" wird aber nur noch sehr vereinzelt etwas empfangen, was wie ich vermute daran liegt, dass der Atmega dann im Verhältnis zu lange die Interrupts deaktiviert hat.

Das beste was mir da jetzt einfallen würde wäre, dass ich dort nun die Zeit verringere, in der die Interrupts deaktiviert sind. Wenn ich einfach nur eine Bytevariable in eine andere Bytevariable kopiere, dann kann da nichts schief gehen, weil alles in einem Schritt passiert, auch wenn sich die ISR dazwischenschiebt, oder? Bei Wordvariablen muss man da wohl aufpassen.

Aber wie sieht das in Bascom mit Bitvariablen aus? Kann es da Fehler beim Lesen/Schreiben geben, wenn die ISR genau dann einspringt, wenn die Bitvariable bearbeitet wird?

Und wie sieht das zeitlich mit "enable Interrupts" und "disable Interrupts" aus? Macht es da Sinn die Interrupts vor und nach jeder Variable zu deaktivieren und aktivieren oder lieber nur einmal am Anfang und Ende?

Also lieber...


disable interrupts
wordvariable1 = wordvariable2
enable interrupts
If A = B Then
disable interrupts
wordvariable3 = wordvariable4
enable interrupts
End If

...oder doch...


disable interrupts
wordvariable1 = wordvariable2
If A = B Then
wordvariable3 = wordvariable4
End If
enable interrupts

...?

MfG

Dunuin

Besserwessi
26.06.2011, 12:09
Man muss den Interrupt nur dann atomar machen, wenn die Variable in einer ISR auch verändert werden kann.
Die Befehle "enable Interrupts" und "disable Interrupts" sollten sehr schnell und kurz sein (1-2 Worte und Zyklen) die lassen sich nämlich direkt in ASM Befehle SEI (ggf. noch ein NOP dazu) und CLI übersetzen. Da kann man also ruhig mehrmals kurz die Interrupts sperren.

Wie lange die Interrupts insgesamt gesperrt sind ist oft nicht so wichtig. Störungen kann es geben wenn Interrupts zu lange in eins unterbrochen sind. Da kann es ggf. sogar sinnvoll sein die Interrupts nur kurz wieder frei zu geben auch wenn der nächste Befehl schon wieder ein "disable Interrupts"ist.

Das verhalten mit dem Wait 100 ms und Wait 1 ms ist schon verdächtig. Da ist vermutlich ein Fehler drin, der bei der längeren Wartezeit nur seltener auftritt.

PicNick
27.06.2011, 09:29
Bascom braucht für BitVarable ein ganze Reihe Instruktionen,
http://www.rn-wissen.de/index.php/Bascom_Inside-Code#Bitvariable
d.h. wenn Hauptschleife u. ISR konkurrenzierend damit werken, musst du in der Hauptschleife das ganze mit dis- u. enable einrahmen.
(http://www.rn-wissen.de/index.php/Bascom_Inside-Code#Bitvariable)
Bei zu langem "disable interrupts" kann es allerdings passieren, dass ISR-Ereignisse verschluckt werden,
sprich, die Unterbrechung muss kürzer sein als die zeit zwischen zwei Interrupts, is aber logo.