Forum: Compiler & IDEs GCC Codeoptimierung: Probleme


von Jan (Gast)


Lesenswert?

Hallo,

ich bin langsam am Verzweifeln. Vieleicht kann mir ja jemand von euch 
helfen.

Ich habe ein Projekt für einen AtMega644p mit dem AVR Studio 4.19 in cpp 
geschrieben.

Es sind einige Variablen mit "extern" in einer Header Datei deklariert, 
die ich in mehreren cpp Dateien einbinde. So haben alle Cpp Dateien 
Zugriff auf diese Variablen. In der Cpp datei mit der main() Funktion 
sind die Variablen auch implementiert worden.

In den Variablen können Werte von 0 bis 255 gespeichert werden. An Hand 
dieser Werte wird mit einem Timer0 in einer ISR ein PWM Signal auf 
angeschlossene RGB LED generiert.

Ein weiterer Timer1 ist so programmiert, dass er Millisekunden Zählen 
kann.

In der Main Funktion habe ich zunächst einige Test Werte in die 
Variablen für die LEDs geschrieben. Es stellen sich die richtigen 
Helligkeiten an den einzelnen Farben ein.

In der While(1) Schleife kommt jetzt das Problem.

Hier steht der Folgende code:
1
while(1)
2
  {
3
    if (Millisekunden > 200)
4
    {
5
      Gruen1 = 0;
6
      Blau1 = 120;
7
    }
8
9
    if (Millisekunden > 5000)
10
    {
11
      Gruen1 = 120;
12
      Blau1 = 0;
13
    }
14
  
15
    //USART0_send_String("T;");
16
  }

Es sollte also erst nach 200ms die Blaue LED schwach Leuchten. Nach 5 
Sekunden dann die Grüne und die Blaue soll aus gehen. (Ist nur für einen 
Test)

Bei der Ausführung dieses Programms, bleiben die Grüne und die Blaue LED 
aber aus. Wenn ich den auskommentierten USART0 send Befehl wieder mit 
kompilieren lassen, funktioniert alles wie gewollt.

mache ich anstatt dem USART0 send ein _delay_ms(2), bleiben auch alle 
LEDs aus.

Stelle ich die Compiler Optimierungsoption um, von Os auf O0, so geht 
auch mit auskommentierten USART0 send erst die Blau LED an. Nach 5 
Sekunden auch die Grüne. Die Blaue erlischt aber nicht.

Ich habe die AVR Toolchain, MinGW und WinAVR Probiert. Überall das 
gleiche Verhalten. Der Code muss ich richtig sein, sonst würde ja mit 
aktiviertem USART0_send auch nicht gehen. Der Controller hängt sich 
nicht auf. Das erkenne ich an einem 2. LED Lichtband, indem ich mit Rot2 
= 20 ein schwach leuchtendes Rot anzeigen lasse.

von (prx) A. K. (prx)


Lesenswert?

Schuss ins Blaue: volatile vergessen.

von Falk B. (falk)


Lesenswert?

@  Jan (Gast)

>Es sind einige Variablen mit "extern" in einer Header Datei deklariert,
>die ich in mehreren cpp Dateien einbinde. So haben alle Cpp Dateien
>Zugriff auf diese Variablen. In der Cpp datei mit der main() Funktion
>sind die Variablen auch implementiert worden.

Widerspruch. Wenn die Variablen global sein sollen, müssen sie AUßERHALB 
von main() definiert sein.

>Stelle ich die Compiler Optimierungsoption um, von Os auf O0, so geht
>auch mit auskommentierten USART0 send erst die Blau LED an. Nach 5
>Sekunden auch die Grüne. Die Blaue erlischt aber nicht.

Wahrscheinlich fehlt ein volatile.

von Jan (Gast)


Lesenswert?

Danke für die Schnellen antworten.

Das volatile hatte ich tatsächlich nur an der Millisekunden Variable. 
Nachdem ich da das auch vor alle Farb Variablen geschrieben habe, geht 
erst das Blaue an, dann das Grüne. Das blaue aber nicht aus. Auch mit 
der -Os optimierung. Vorher ging bei dieser Optimierung ja garnichts.

Das ist kein Wiederspruch. Die Variablen sind nicht in der main() 
definiert, sondern in der selben cpp Datei, inder sich die main() 
befindet aber außerhalb der main().

Also nun steht vor jeder verwendeten Variablen ein volatile und es geht 
trotzdem nur, wenn ich das USART0_send aktiviere.

von Jan (Gast)


Lesenswert?

Was vieleicht noch interessant ist:

Als c Programm funktioniert das Ganze. Dann kann ich aber meine Objekte, 
die ich später benötige nicht mehr verwenden.

von wörg (Gast)


Lesenswert?

Meist stecken solche Fehler immer in den Codeabschnitten, die nicht 
gepostet wurden. ;) Die Frage ist, wie hast du denn deinen Timer
> so programmiert, dass er Millisekunden Zählen
> kann

von Jan (Gast)


Lesenswert?

Wenn das ganze funktioniert, wenn den auskommentierten USART0_send 
Befehl wieder einkommentiere, dann ist doch wohl davon auszugehen, dass 
mit dem Timer und dem restlichen Code soweit alles stimmt oder nicht?

der AtMega läuft auf 16 MHz
Der Voteiler steht bei 64
im Compare Register A steht 2500

der Interrupt kommt alle 10ms

in der IST wird immer Millisekunden+=10 gerechnet.

Wie gesagt. Das ganze geht ja auch, wenn ich in der while(1) Schleife 
etwas mit USART Versende

von Walter S. (avatar)


Lesenswert?

Jan schrieb:
> Wenn das ganze funktioniert, wenn den auskommentierten USART0_send
> Befehl wieder einkommentiere, dann ist doch wohl davon auszugehen, dass
> mit dem Timer und dem restlichen Code soweit alles stimmt oder nicht?

nein, dass der restliche Code nicht stimmt kannst Du daran erkennen dass 
er nicht geht!

Mein Rat:
Das ganze Programm soweit kürzen dass der Fehler noch auftritt und sich 
dann hier wieder melden MIT dem Programmtext

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.