WinAVR optimiert Wertzuweisung weg?!

OP Persönliche Seite #2120302
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...
Angehängte Dateien:
OP Persönliche Seite #2120338
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...
Gast #2124146
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...
Gast #2124165
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

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.