Servus zusammen,
ich grüble gerade ein wenig (ohne konkrete Anwendung, mehr so allgemein)
ob es einen bequemen Weg gibt volatile-deklarierte Variablen innerhalb
von Interrupts normal zu behandeln. Anwendung wären beispielsweise
Status-bytes, die für eine Interruptroutine sowieso neu aus dem Speicher
geladen und hinterher gespeichert werden müssen. Deren Verwendung im
Interrupt könnte dann aber vom Compiler gut optimiert werden. Im
Hauptprogramm müssen sie allerdings volatile sein. Damit nicht 2
Versionen der gleichen Variable im Speicher und in einem Register
entstehen kann. (Wofür man volatile halt brauchen kann).
Kennt da jemand einen Weg? irgend einen trickreichen Cast zu beginn der
Interruptroutine oder so etwas?
Danke für Antworten,
Gruß Willi
Willi S. aus M. schrieb:> Anwendung wären beispielsweise> Status-bytes, die für eine Interruptroutine sowieso neu aus dem Speicher> geladen und hinterher gespeichert werden müssen. Deren Verwendung im> Interrupt könnte dann aber vom Compiler gut optimiert werden. Im> Hauptprogramm müssen sie allerdings volatile sein.
Und wie steht es um nested interrupts?
Willi S. aus M. schrieb:> Kennt da jemand einen Weg? irgend einen trickreichen Cast zu beginn der> Interruptroutine oder so etwas?
falscher Ansatz. die ISR ist ja nicht das Problem. Einfach die Variabel
nicht als Volatile kennzeichen.
Im Hauptprogramm dann auf volatile casten.
int i;
*(volatile int*)&i = xxx;
so in der art.
??? schrieb:> Und wie steht es um nested interrupts?
dort gibt es das Optimierungsproblem überhaupt nicht. Dort muss man nur
darauf achten das die variabel als Atomic behandelt wird.
??? schrieb:> Peter II schrieb:>> Dort muss man nur darauf achten das die variabel als>> Atomic behandelt wird.>> Nö, da kann man volatile nutzen.
Dennoch muß der Zugriff atomar sein. volatile Zugriff hat mit atmoar
zunächst nichts zu tun, d.h. volatile Variablen oder SFRs werden vom
Compiler nicht atomar behandelt.
??? schrieb:> Nö, da kann man volatile nutzen
nein kann man nicht.
ein volatile hat nichts mit einen Atomic zugriff zu tun. Den braucht man
z.b. bei einen int16 auf einem 8bit System.
??? schrieb:> und was hat das mit der Ausgangsfrage zu tun?
nichts es war die Beantwortung von
> Peter II schrieb:> > Dort muss man nur> > darauf achten das die variabel als Atomic behandelt wird.> Nö, da kann man volatile nutzen.
Ich gebe zu, nested interrupts sind ein Problem, aber das sind sie so,
oder so. da hilft ggf. auch kein volatile.
Mir geht es mehr darum, dass volatile ja durchaus manchmal sinnvoll ist,
aber häufig eben nur in bestimmten Programmsequenzen.
Der Ansatz
Peter II schrieb:> Im Hauptprogramm dann auf volatile casten.>> int i;>> *(volatile int*)&i = xxx;
könnte durchaus die Ersehnte Lösung sein, ist aber ziemlich unschön zu
Programmieren. Angenehmer und vor allem leserlicher wäre es hier bereits
mit einem define den "*(volatile int*)&" block abzukürzen. Noch schöner
wäre es im entsprechenden Programmabschnitt eine einleitende Anweisung
zu geben die besagt: Hier bitte mit oder ohne volatile.
Johann L. schrieb:> Lies die Variable in der ISR einfache in eine lokele Kopie ein und> fertig.
hier muss ich am ende Manuel die Kopie wieder zurück speichern, was zwar
auch schon recht ordentlich ist, aber ein großes Potential für Fehler
bietet.
Nunja mal sehn vielleicht kommt ja noch DIE LÖSUNG zu tage, auch wenn
ich mit den bisherigen definitiv Leben kann... Ich bin halt ein kleiner
Perfektionist.
Danke euch
Gruß Willi
Willi S. aus M. schrieb:> Johann L. schrieb:>> Lies die Variable in der ISR einfache in eine lokele Kopie ein und>> fertig.>> hier muss ich am ende Manuel die Kopie wieder zurück speichern, was zwar> auch schon recht ordentlich ist, aber ein großes Potential für Fehler> bietet.
Aha, und der (vergessene) Cast auf volatile in jeder anderen Stelle
des Programms ist also kein Problem...
Und für das vergessene Rückschreiben gibt's sogar Warnings vom GCC wie
"value is set but not used".
> Nunja mal sehn vielleicht kommt ja noch DIE LÖSUNG zu tage, auch wenn> ich mit den bisherigen definitiv Leben kann... Ich bin halt ein kleiner> Perfektionist.
Perfekter als perfekt geht eben nicht.
Das sieht zwar furchtbar ineffizient aus, aber mit Optimierungen an (-O2
bei GCC) wird daraus genau der Code, den man haben will: Lade den Wert
aus x, multipliziere ihn mit 924, schreibe ihn zurück nach x. Die
geschweiften Klammern sorgen dafür, dass xb nur innerhalb davon gültig
ist, und beim } wird der Destruktor aufgerufen und der Wert automatisch
zurückgeschrieben, sofern er geändert wurde. Die Variable x wird
innerhalb der Klammern (garantiert) nur genau 1x gelesen und nur 1x
geschrieben. Falls der Compiler den Operator-Aufruf nicht automatisch
hinbekommt, muss man ggf. explizit über xb.get() bzw. xb.set()
nachhelfen.
@ Willi S. aus M. (Gast)
>hier muss ich am ende Manuel die Kopie wieder zurück speichern, was zwar>auch schon recht ordentlich ist, aber ein großes Potential für Fehler>bietet.
???
Das muss man auch in Normalfall, mit der lokalen Kopie spart man sich
halt einige Takte für das mehrfache Lesen und Schreiben.
1
volatileintmuh;
2
3
ISR(melken){
4
5
intmäh=muh;
6
7
mäh++;
8
if(mäh==VOLL){
9
muh=0;
10
}
11
}
>Nunja mal sehn vielleicht kommt ja noch DIE LÖSUNG zu tage, auch wenn>ich mit den bisherigen definitiv Leben kann... Ich bin halt ein kleiner>Perfektionist.
Ich glaube eher ein Pedant . . .
https://de.wikipedia.org/wiki/Pedanterie
Willi S. aus M. schrieb:> könnte durchaus die Ersehnte Lösung sein, ist aber ziemlich unschön zu> Programmieren
Seit wann erhebt C den Anspruch, schön zu programmieren zu sein.
Ganz ohne C-Schweinerei geht es wohl nicht.
Daher gleich noch eine obendrauf:
Man definiere die Variable in einem eigenen Interruptmodul und
deklariere die Variable in der Headerdatei als volatile. Die Headerdatei
wird nicht vom Interrruptmodul includiert.
Kommentare an sinnvollen Stellen machen die Sache relativ eigensicher.
Peter Dannegger, dem hier wohl einige doch Einiges zutrauen, verwendet
den oben beschriebenen "Hack", die Variable beim Zugriff im
Hauptprogramm auf volatile zu casten. Habe mich vor ein paar Jahren erst
auch gewundert, aber das macht Sinn. Und mit einem Macro, ist es im
Programmtext auch recht gut zu lesen und zu schreiben.
Verwendet wurde es von P.D. z.B in seinem Software-UART (hier im Forum
zu finden).