While Schleife wird nur durch printf beendet

Gast #1936089
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
Gast #1936141
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.
#1936144
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.
Gast #1936150
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.
Gast #1936152
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.
Gast #1936166
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
Gast #1936175
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')
Gast #1936180
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.
#1936182
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.
#1936186
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 ;-).
Gast #1936191
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- :-)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren