Forum: Compiler & IDEs WinAVR optimiert Wertzuweisung weg?!


von Markus F. (5volt) Benutzerseite


Angehängte Dateien:

Lesenswert?

Hallo,
ich habe gerade ein kleines Problem mit WinAVR.

Und zwar habe ich ein Programm (Sourcecode habe ich angehängt), das auf 
ein Zeichen von der seriellen Schnittstelle wartet und dann INT0 und 
Timer0 aktiviert.
Sobald entweder INT0 ausgelöst wird oder der Timer-Overflow-Interrupt 
78mal ausgelöst wurde, werden diese beiden Interrupts deaktiviert und 
der ADC im Free-Run-Modus (mit Interrupt) aktiviert.
Der ADC macht dann 741 Wandlungen und schickt die Daten per RS232 an den 
PC; dann wird der ADC wieder deaktiviert und das Programm wartet auf das 
nächste Zeichen von der seriellen Schnittstelle.

Das Ganze soll ein kleines digitales Speicheroszilliskop werden: An INT0 
hängt ein Komparator für die Triggerung:
Der PC, an den das Teil (über einen FT232) angeschlossen ist, sendet ein 
Startsignal an den AVR. Von da an wartet der AVR auf den Triggerimpuls 
an INT0. Sobald ein Triggerimpuls kommt - oder wenn nach 80ms immer noch 
keine Triggerung erfolgt ist (dafür der Timer) - startet der ADC und 
macht mit 9,259kHz Samplingrate 741 Messungen und schickt die gemessenen 
Werte zum PC.
Am PC wird das dann eben in einem Diagramm dargestellt. Dann schickt das 
PC-Programm ein neues Startsignal an den AVR und der Zyklus beginnt von 
neuem.

Ok, zurück zum Problem:
Der Timer-Overflow-Interrupt inkrementiert eine Variable (im Code ist 
das timcnt), um nach 78 Timer-Overflow-Interrupts den ADC zu starten. 
Und diese Variable wird eigentlich beim Start eines neuen Zyklus wieder 
auf Null gesetzt (Zeile 31 im Code).
So, aber wenn ich die Compiler-Optimierung auf O2, O3 oder Os stelle 
erfolgt diese Wertzuweisung nicht (ich habe mir auch die lss-Datei 
angesehen; da ist diese Zuweisung auch nicht drin).. Dann läuft die 
Variable alle paar 10 Messungen über, was reproduzierbar 
Fehltriggerungen produziert.
Schalte ich die Optimierung aber ab oder stelle sie auf O1, klappt alles 
wie es soll.
Ich habe also den starken Verdacht, dass der Compiler die Zuweisung 
"timcnt = 0" einfach wegoptimiert...

Was meint ihr: Ist das ein Bug in avr-gcc/WinAVR? Oder habe ich einfach 
irgendwas falsch gemacht...

von Helfer (Gast)


Lesenswert?

Du hast gerade den zweithäufigsten Fehler gemacht, den man beim 
Interruptprogrammieren machen kann. Schau dir den Abschnitt über 
volatile im Artikel Interrupt an.

von Markus F. (5volt) Benutzerseite


Lesenswert?

Helfer schrieb:
> Du hast gerade den zweithäufigsten Fehler gemacht, den man beim
> Interruptprogrammieren machen kann. Schau dir den Abschnitt über
> volatile im Artikel Interrupt an.

Vielen Dank, damit geht es.
Das Blöde an sowas ist ja: In vielen Fällen funktioniert es auch ohne 
das volatile problemlos. Ich habe schon einge andere AVR-Programme mit 
Interrupts und Datenaustausch mit dem Hauptprogramm geschrieben; und da 
hat auch ohne volatile der Compiler die Wertzuweisungen noch nie 
wegoptimiert...
Naja, wieder was gelernt...

von Klaus (Gast)


Lesenswert?

Helfer schrieb:
> Du hast gerade den zweithäufigsten Fehler gemacht, den man beim
> Interruptprogrammieren machen kann. Schau dir den Abschnitt über
> volatile im Artikel Interrupt an.

Und der dritthäufigste Fehler: Dem Compiler die Schuld geben. Was täten 
wir nur ohne die vielen Anfänger, die in den Compilern die ganzen Bugs 
finden, welche die Profis sonst nie entdeckt hätten...

von Oliver (Gast)


Lesenswert?

Markus Frejek schrieb:
> Ich habe schon einge andere AVR-Programme mit
> Interrupts und Datenaustausch mit dem Hauptprogramm geschrieben; und da
> hat auch ohne volatile der Compiler die Wertzuweisungen noch nie
> wegoptimiert...

Tja, Fehler Nummer vier: Ham'wer schon immmer so gemacht. Nur, weil 
etwas (anscheinend) funktioniert, ist es noch lange nicht richtig ;)

Frühere Versionen des gcc (3.xx) waren bei der Optimierung an dieser 
Stelle zurückhaltender, da ging das auch ohne volatile. Die aktuellen 
gcc's nutzen die C-Sprachnorm da gandenloser aus, und dazu gehört eben 
auch das wegoptimieren von aus Compilersicht sinnlosen Zuweisungen. Und 
ja, der darf das ;)

Oliver

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
Noch kein Account? Hier anmelden.