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


von Jens (Gast)


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.
1
while (!(flip_status_reg & (1 << flip_current_decayed))) {
2
  printf("loop1");
3
}

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

bricht niemals ab.
Die ISR, in der das Flag gesetzt wird:
1
ISR (TIMER2_OVF_vect) {
2
  if(soft_counter_timer2++ >= (F_CPU/(32*256))/(1/0.045)) {
3
    soft_counter_timer2 = 0;
4
    flip_status_reg |= (1<<flip_current_decayed);
5
    if(flip_status_reg & (1 << flip_current_decayed)) {
6
      printf("flag gesetzt");
7
    }
8
  }
9
}
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

von Glaskugel (Gast)


Lesenswert?

volatile

von Jens (Gast)


Lesenswert?

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

von g457 (Gast)


Lesenswert?

Zeig mal den kompletten Code.

von U.R. Schmitt (Gast)


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.

von g457 (Gast)


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.

von (prx) A. K. (prx)


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.

von g457 (Gast)


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.

von Jens (Gast)


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.

von (prx) A. K. (prx)


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.

von Jens (Gast)


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

von Glaskugel (Gast)


Lesenswert?

Sag ich doch: volatile!

von U.R. Schmitt (Gast)


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')

von Jens (Gast)


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.

von Peter (Gast)


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.

von (prx) A. K. (prx)


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.

von Klaus W. (mfgkw)


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.

von (prx) A. K. (prx)


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 ;-).

von (prx) A. K. (prx)


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.

von Glaskugel (Gast)


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- :-)

von Klaus W. (mfgkw)


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.

von Klaus W. (mfgkw)


Lesenswert?

A. K. schrieb:
> Der einzige Fliesskommawert in diesem Ausdruck ist eine Konstante.

jaja, gut, ich sage schon nichts mehr.

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.