mikrocontroller.net

Forum: Compiler & IDEs While Schleife wird nur durch printf beendet


Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

wir sitzen hier gerade vor einem sehr seltsamen Bug.
Es gibt in unserem Programm 2 while schleifen, die nur dann korrekt 
durchlaufen werden, wenn im Rumpf einmal printf() ausgeführt wird.
Die Schleifen dienen dazu, abzuwarten, bis von einem Timer ein Flag 
gesetzt wird.
while (!(flip_status_reg & (1 << flip_current_decayed))) {
  printf("loop1");
}

Das Flag wird auch gesetzt, das haben wir im Timer Interrupt ausgeben 
lassen.
Das ist das verrückte,
while (!(flip_status_reg & (1 << flip_current_decayed)));

bricht niemals ab.
Die ISR, in der das Flag gesetzt wird:
ISR (TIMER2_OVF_vect) {
  if(soft_counter_timer2++ >= (F_CPU/(32*256))/(1/0.045)) {
    soft_counter_timer2 = 0;
    flip_status_reg |= (1<<flip_current_decayed);
    if(flip_status_reg & (1 << flip_current_decayed)) {
      printf("flag gesetzt");
    }
  }
}
mit der gleichen Bedingung wie in der Schleife, das funktioniert auch, 
das
Flag wird erkannt und der String ausgegeben.

Wir stehen hier echt auf dem Schlauch, da wir keinen Zusammenhang 
zwischen der Schleife und printf erkennen.

Gibt es irgendeinen Fehler, den man machen kann, der zu solch scheinbar 
undefiniertem Verhalten führt?

Vielen Dank schonmal

Autor: Glaskugel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
volatile

Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, leider ändert das nichts, obwohl es natürlich offensichtlich zu 
so einem Verhalten führt.

Autor: g457 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zeig mal den kompletten Code.

Autor: U.R. Schmitt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie oft wird der Timerinterrupt aufgerufen?
Euch ist schon klar, daß ein printf ein ziemlich teurer Funktionsaufruf 
ist?
Auch die Flieskommarechnung dürfte nicht ganz billig sein.

Autor: g457 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Auch die Flieskommarechnung dürfte nicht ganz billig sein.

Welche? Die die der (anständige) Compiler (bzw. dessen Optimierer) schon 
ausgerechnet hat? :-)

Nichtsdestotrotz wird man mit ohne Code nicht viel mehr weiter helfen 
können als rumraten.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
g457 schrieb:

> Welche? Die die der (anständige) Compiler (bzw. dessen Optimierer) schon
> ausgerechnet hat? :-)

Diese:
 if(soft_counter_timer2++ >= FloatingPointConstant) {

Die Rechnung wird nämlich nicht zurück zu int gecastet und so hat man 
einen Fliesskommavergleich in der ISR.

Wäre trotzdem nützlich, auch die Deklaration der Variablen zu sehen.

Autor: g457 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Die Rechnung wird nämlich nicht zurück zu int gecastet und so hat man
> einen Fliesskommavergleich in der ISR.

Verlgeich != Rechnung. Aber wollen wir mal keine Korinthen ausscheiden 
und zum eigentlichen Problem zurückkehren: der TO hat den Code noch 
nicht gezeigt.

Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der ganze Code ist sehr sehr umfangreich, es kommen noch diverse Libs 
hinzu und andere Funktionalitäten mit Bausteinen, die über SPI 
angeschlossen sind.

Deshalb habe ich den relevanten Teil gepostet.
Kann überhaupt irgendein Code drumerherum bauen, sodass der das 
Verhalten in der ISR und der Schleife beeinflusst?

while (!(flip_status_reg & (1 << flip_current_decayed)));
     2da:       80 91 ee 02     lds     r24, 0x02EE
     2de:       82 ff           sbrs    r24, 2
     2e0:       61 c0           rjmp    .+194           ; 0x3a4

[...]

3a4:       ff cf           rjmp    .-2             ; 0x3a4

Das sieht doch sehr nach einer Endlosschleife aus.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jens schrieb:

> Das sieht doch sehr nach einer Endlosschleife aus.

Was nur beweist, dass die Variable hier nicht volatile ist. Ohne 
volatile ist das definitiv Unsinn und genau das kommt dabei raus.

Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:
> Die Rechnung wird nämlich nicht zurück zu int gecastet und so hat man
> einen Fliesskommavergleich in der ISR.

Das stimmt in der Tat, es wird ein Fließkommavergleich durchgeführt, 
danke für den Hinweis.

Ich hatte die falsche Variable mit volatile deklariert, jetzt gehts 
einwandfrei!

Vielen Dank

Autor: Glaskugel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sag ich doch: volatile!

Autor: U.R. Schmitt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jens schrieb:
> Deshalb habe ich den relevanten Teil gepostet.

Dazu gehört aber zumindest die Variablendeklaration.

g457 schrieb:
> Welche? Die die der (anständige) Compiler (bzw. dessen Optimierer) schon
> ausgerechnet hat? :-)

Wo Du recht hast hast Du recht :-) Trotzdem wenn der TE mit dem Timer 
einen 500KHz Takt erzeugen will wirds ganz schnell eng. Und oft genug 
ist völliges Unverständnis da wei viel Zeit so ein paar Buchstaben wie 
"printf" dann im µC brauchen (Ehe sich jemand auf den Schlips getreten 
fühlt, ich sagte 'oft')

Autor: Jens (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Glaskugel schrieb:
> Sag ich doch: volatile!

Jo der Hammer, wir sitzen seit Stunden an dem Problem und du postest die 
Lösung nach zwei Minuten.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jens schrieb:
>> Die Rechnung wird nämlich nicht zurück zu int gecastet und so hat man
>> einen Fliesskommavergleich in der ISR.
>
> Das stimmt in der Tat, es wird ein Fließkommavergleich durchgeführt,
> danke für den Hinweis.

wo sind denn jetzt die leute die Sagen das compiler mittlerweile sehr 
gut optimieren? Was macht es für ein sinn ein float-int vergleich mit 
einem convert von int zu float zu machen?
Mir fällt kein sinnvoller Grund sein. Es kann ja schon sein das die 
Spezifikation es so will, aber wenn das Ergebniss gleich ist darf der 
compiler doch optimieren.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jens schrieb:

> Jo der Hammer, wir sitzen seit Stunden an dem Problem und du postest die
> Lösung nach zwei Minuten.

Dieses Problem gehört zu den häufigsten im Forum überhaupt. Wenn in 
einer Frage eine ISR enthalten ist und sich das Programm seltsam 
benimmt, dann kann man einfach mal blind "volatile" in die Runde werfen 
und hat eine hohe Trefferquote.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter schrieb:
> Mir fällt kein sinnvoller Grund sein. Es kann ja schon sein das die
> Spezifikation es so will, aber wenn das Ergebniss gleich ist darf der
> compiler doch optimieren.

float hat einen viel größeren Wertebereich, deshalb kann ein Compiler 
nicht einfach mit int stattdessen rechnen.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter schrieb:

> Mir fällt kein sinnvoller Grund sein. Es kann ja schon sein das die
> Spezifikation es so will, aber wenn das Ergebniss gleich ist darf der
> compiler doch optimieren.

Yep, das wäre hier prinzipiell möglich, aber die Motivation seitens der 
Autoren des Compilers, Programmierfehler durch Optimierung zu 
beschleunigen, ist offenbar nicht gross genug ;-).

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Wachtler schrieb:

> float hat einen viel größeren Wertebereich, deshalb kann ein Compiler
> nicht einfach mit int stattdessen rechnen.

Der einzige Fliesskommawert in diesem Ausdruck ist eine Konstante.

Autor: Glaskugel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Dieses Problem gehört zu den häufigsten im Forum überhaupt. Wenn in
>einer Frage eine ISR enthalten ist und sich das Programm seltsam
>benimmt, dann kann man einfach mal blind "volatile" in die Runde werfen
>und hat eine hohe Trefferquote.

Stimmt. Mit Überlegung hatte das nichts zu tun. Aber ich bin ja eine 
Glaskugel. Ich habe das geespert- :-)

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Wachtler schrieb:
> float hat einen viel größeren Wertebereich, deshalb kann ein Compiler
> nicht einfach mit int stattdessen rechnen.

das war natürlich ein Eigentor; bei einem Vergleich float gegen int 
hilft der größere Wertebereich ja auch nichts mehr.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:
> Der einzige Fliesskommawert in diesem Ausdruck ist eine Konstante.

jaja, gut, ich sage schon nichts mehr.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.