Hi, ich habe eine WinAVR Anwendung in der serielle Eingangsdaten per ISR in einen Ringbuffer geschrieben werden. In der Auslesefunktion überwache ich, das ich den Pointer auf die Eingangsposition nicht überhole. Mit der -Os Optimierung wird aber leider die Übernahme der momentanen Eingangsposition dummerweise vom Compiler optimiert vor die Warteschleife gesetzt. Codebeibspiel das nicht funktioniert: ----- char* psaveInputpos; // diese Schleife soll das Überholen der Eingangsposition verhindern do{ cli(); psaveInputpos = prInputpos; sei(); }while(psaveInputpos == prOutputpos); //hier gehts dann weiter mit dem Abholen der neuen Daten ---- im Assembler Listing kann man sehen, das die Anweisung psaveInputpos = prInputpos; vor die while Schleife gesetzt wird und damit funktioniert die Abfrage natürlich nicht mehr. Gelöst habe ich das Problem indem ich den Positionsvergleich in eine getrennte Funktion ausgelagert habe, die ich allerdings dann noch als noinline deklarieren musste, sonst war es das selbe in grün. Gibt es für solche Fälle Compiler Direktiven, die die Position einer Anweisung gezielt für eine Funktion oder innerhalb einer Funktion sicherstellen? Gruß Ingo
Ja, gibt es: die vom Interrupt-Handler modifizierte Variable als volatile deklarieren.
Hi prx, die sind natürlich volatile, selbst die Funktions interne zusätzlich als volatile zu definieren bringst nicht. Der Compiler setzt sie trotzdem vor die while Schleife :-(( Gruß Ingo
Vertrauen ist gut, Kontrolle ist besser. Ich sehe nirgends ein volatile. Vorsorglicher Tipp: in volatile char *p; zeigt ein non-volatile Pointer auf volatile char, in char *volatile p; ist der Pointer selbst volatile.
Ingo Stahl schrieb: > Gibt es für solche Fälle Compiler Direktiven, die die Position einer > Anweisung gezielt für eine Funktion oder innerhalb einer Funktion > sicherstellen? Nö. Der Compiler darf und wird die Reihenfolge der Anweisungen so umstellen, wie es es für sinnvoll hält. Das macht er das so, daß sich dabei am Ergebnis nichts ändert (wenn er keine Bug hat) . Ingo Stahl schrieb: > Der Compiler setzt sie trotzdem > vor die while Schleife :-(( Bist du dir sicher? Optimierter Code ist schwer zu lesen. Die als Kommentar eingefügten C-Sourcecodezeilen kannst du als Anhaltspunkt dabei getrost vergessen. Zeig mal ein compilierbares Codebeispiel, an dem sich das Verhalten reproduzieren lässt. Oliver
Hi, @prx: so sind sie global definiert: volatile char* prInputpos; volatile char* prOutputpos; die Anweisung psaveInputpos = prInputpos; gibt ein natürlich ein Warning, den Cast psaveInputpos = (char*)prInputpos; hatte ich vergessen mit anzuführen. Wobei ich ja auch die Variante volatile char* psaveInputpos; erfolglos ausprobiert hatte. @Oliver: ich baue morgen mal wieder die alte Variante ein und zeige das Codebeispiel. Sicher bin ich mir schon, ich bin beim Debugging (Dragon) auf die Assembler Ansicht gegangen. Ohne Optimierung sieht man, das der Compiler die Anwweisung nicht verschiebt. Gruß Ingo
Ingo Stahl schrieb: > so sind sie global definiert: > volatile char* prInputpos; > volatile char* prOutputpos; Na also, dachte ich mir es doch. Die Pointer sind hier eben nicht volatile, auch wenn's für ungeübte Augen zunächst so aussieht, und daher gibst du dem Compiler die ungewollte Freiheit der Optimierung. Damit deklarierst du, dass die chars, auf die die Pointer zeigen, volatile sind. Nicht die Pointer. Bei deinem Vergleich geht es aber um die Pointer, nicht die chars. Wenn du das grade ziehst bist du nebenbei auch ganz ohne cast die Warnung los. Also: char *volatile prInputpos; char *volatile prOutputpos;
Hi, jetzt wollte ich es doch noch wissen und hab das Problem in einem Testprojekt nachvollzogen. @prx: Super Tipp, das wars! Im Assembler Listing ist es einwandfrei sichtbar. Irgentwie werde ich mit der für mich etwas kryptischen "C" Syntacs" trotz einiger Jahre VC++ nicht 100%tig so warm, das mir das auf Anblick auffällt. @Oliver: ich denke, das sich das Codebeispiel damit erledigt hat. Gruß Ingo
Ingo Stahl schrieb: > @Oliver: > ich denke, das sich das Codebeispiel damit erledigt hat. ;-) Oliver
Oliver schrieb: > Ingo Stahl schrieb: >> @Oliver: >> ich denke, das sich das Codebeispiel damit erledigt hat. hmmm, nicht wirklich. Zwar wird die störende Optimierung nicht mehr gemacht, aber es sieht stark danach aus, daß da noch ne Race-Condition zuschlagen kann wegen nicht-atomarem Code im Zeiger-Test.
Wenn prOutputpos in der ISR nicht verändert wird (was zu vermuten ist), dann nicht. Oliver
Oliver schrieb: > Wenn prOutputpos in der ISR nicht verändert wird (was zu vermuten ist), > dann nicht. > > Oliver genau, da fummelt keine ISR dran rum :-) Gruß Ingo
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.