Volatile ist nicht genug hier. Das macht nur dem Compiler bewusst, dass
die Variable auch außerhalb der Context geändert werden kann. Deswegen
wird praktisch beim jeden lese zugriff auf die Variable noch einmal
gelesen. Bzw schreiben wird auch sofort abgesetzt. Aber Vorsicht, der
Compiler weiß nichts von dem Cache. Der kann immer noch Probleme machen.
Und der Compiler weiss auch nicht wie der CPU aufgebaut ist, ob der
intern nochmal schreibefehle speichern kann. Es ist oft so, dass der RAM
ECC bits hat, und eine Granularität von 8,16 oder 32 bytes sogar. Das
heisst, es lohnt sich nicht sofort einen Read Modify Write zu machen, um
8 bits zu schreiben, weil der über den Bus gehen muss und letztendlich
werden im RAM doch 8 bytes geändert. Manche CPUs sammeln hier
schreibbefehle.
In Embedded bereicht hast du sehr oft
MSYNC() und ISYCH() makros im Compiler abstraktion header file.
Diese makros müssen auf den jeweiligen asm befehle gemappt werden. Je
nach Architektur kann es anders heissen.
MSYNCH macht sicher dass alle Schreibaufträge die bisher ausgeführt
worden sind auf den Bus geschickt werden. Manche CPUs haben einen
DataStorage Unit was einige Schreibbefehle speichern kann (wegen
granularität des RAMs). Das heisst, wenn man etwas schreibt, kann sein
dass das screiben gar nicht sofort ausgeführt wird. Manche Kontroller
setzten den nie ab....
ISYNC macht sicher, dass alle Befehle bis zum ISYNC komplett
abgearbeitet werden. Sprich alles ist durch den Pipeline und ist
ausgeführt.
Da ich paranoid bin, würde ich so machen:
ISYNC() <= stellt sicher dass alle Befehle davor durch den CPU
abgearbeitet worden sind
MSYNC() <= stellt sicher dass alle Schreibaufträge auf den Bus gelandet
sind
ISYNC() <= stellt sicher dass der msynch auch abgearbeitet ist.
Vermutlich braucht man das nicht, aber schaden kann es ja nicht.
Am Besten noch darauf achten dass der Cache auch write trough ist, und
beim lesen entweder über nichtgecachte Addresse gehen oder den Cache
invalidieren.