mikrocontroller.net

Forum: Compiler & IDEs Unerklärbares Verhalten


Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

Ich habe schon eine Weile hier im Forum mitgelesen, aber jetzt weiß ich 
absolut nicht weiter!
Ich programmiere für den AT90can128 der ein Display ansteuert (die 
LCD-Funktionen) mit AVR Studio und nutze die aktuellste WinAVR Version 
um aus dem C Code entsprechenden Maschinencode zu bauen. Übertragen wird 
das ganze per PonyProg.
Hier der Code.

LCD_Cls(CO_BG_COLOR);
LCD_Print("Kalibrierung. Ok bestätigt.", STARTX, ENDY, 1, 1, 1, 
CO_PLOT_COLOR, CO_BG_COLOR);
LCD_Print("Anzahl Kalibrierungen:", STARTX, ENDY+10, 1, 1, 1, 
CO_PLOT_COLOR, CO_BG_COLOR);

uint8_t count = enter_value(STARTX,ENDY+20);

if(count == 0) return;

/*char t2[6];
const char * text2 = utoa(count, t2, 10);*/

float calib_values[count];
unsigned int i = 0;
for(;i < count; i++) {
  calibrate(i, calib_values);
}

So würde das ganze nicht laufen. Die for-Schleife terminiert nicht und 
ruft immer wieder calibrate auf. Selbst wenn ich als Durchlaufzahl 1 
angebe, so übergibt er an calibrate zum Teil den Wert 4!

Jetzt kommt aber das Kuriose! Entferne ich die Kommentare dort, sodass 
mein Wert in ein char-Array umgewandelt wird und obwohl ich diesen 
String gar nicht benutze (!!!!!) funktioniert es dann plötzlich. Hat 
jemand dafür eine Erklärung bzw. eine Lösung?

Danke

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klingt nach Stackoverflow, irgendein Pointer der iregndwas überschreibt 
oder sowas in der Art.

Autor: kosmonaut pirx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,
was macht was macht der aufruf enter_value(..) im detail?

klingt für mich, als wenn der optimizer eine annahme trifft, die durch 
das utoa nicht mehr zutrifft.

bye kosmo

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
static uint16_t enter_value(uint8_t x, uint8_t y) {
  uint16_t val = 0;
  char t[10];
  while((PIND & (1 << PIND1)) ) {
    const char * text = utoa(val, t, 10);

    LCD_Print(text, x,y, 1, 1, 1, CO_PLOT_COLOR, CO_BG_COLOR);

    uint16_t val2 = val;
    if(!(PIND & (1 << PIND4)) ) {
      ++val2;
    }
    else if(!(PIND & (1 << PIND7)) ) {
      --val2;
    }

    if( ((uint8_t)log10(val2)) < ((uint8_t)log10(val))) {
      LCD_Print("                        ", x,y, 1, 1, 1, CO_PLOT_COLOR, 
CO_BG_COLOR);
    }

    val = val2;

    if(!(PIND & (1 << PIND6)) ) {
      delay_ms(120);
    }
  }

  delay_ms(150);

  return val;
}

Das macht der Aufruf. Aber ums kurz zu erklären.
Er nimmt Eingaben von drei verschiedenen Tastern entgegen, die am Port D 
hängen.
D4 inkrementiert einen Wert und D7 dekrementiert einen Wert, falls sie 
gedrückt werden.
Die aktualisierten Werte werden dann auch ausgegeben.
D6 dient dazu um Verzögerungen einzubauen, sodass man auch 
Einzelschritte ausführen kann und beim inkrementieren nicht mit einem 
kurzen Druck gleich um 15 den Wert erhöht, weil der Controller so 
schnell ist.
Zusätzlich werden die Taster etwas entprellt.

Sobald ein vierter Taster gedrückt wird, wird die Schleife verlassen - 
dann steht der Wert fest und er wird zurückgegeben.
----------------
Ich kann so auch den Wert 1 eingeben, aber er gelangt trotzdem in die 
Endlosschleife.

Autor: kosmonaut pirx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,
soll heissen, wenn du statt
return val
ein
return 1

definierts (und den optimizer ausschaltest), kommt immer noch die 
endlosschleife?

bye kosmo

Autor: kosmonaut pirx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
aso,
falls, ja, vermute ich ebenfalls einen fehlerhaften pointer. 
möglicherweise greift calibrate auf einen falschen index zu und somit 
irrtümlich auf das vor ihm liegende i.
bye kosmo

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@kosmonaut pirx

Ich habe das gerade mal so geändert, aber kurioserweise kann er nicht 
ohne Compiler Optimization kompilieren. Es ergibt immer folgenden 
Fehler:

avr-gcc.exe -mmcu=at90can128  adc.o font_f-5x8.o glcd-Display3000-211.o 
visualizer.o font_f-8x14.o main.o     -o Test.elf
e:/winavr 
20070525/bin/../lib/gcc/avr/4.1.2/../../../../avr/lib/avr5\libc.a(log.o) 
:  In function `log':(.text.fplib+0x50): relocation truncated to fit: 
R_AVR_13_PCREL against symbol `__addsf3' defined in .text section in 
e:/winavr 20070525/bin/../lib/gcc/avr/4.1.2/avr5\libgcc.a(_addsub_sf.o)

e:/winavr 
20070525/bin/../lib/gcc/avr/4.1.2/../../../../avr/lib/avr5\libc.a(modf.o 
):  In function `modf':
(.text.fplib+0x42): relocation truncated to fit: R_AVR_13_PCREL against 
symbol `__addsf3' defined in .text section in e:/winavr 
20070525/bin/../lib/gcc/avr/4.1.2/avr5\libgcc.a(_addsub_sf.o)

make: *** [Test.elf] Error 1

Also er findet da irgendeinen Fehler in einer Bibliotheksfunktion, ka, 
was ich da machen soll.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast vergessen, gegen die libm.a zu linken (Option -lm).

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Jörg, für den Tipp.

Also mit deaktivierten Optimierungen funktioniert es wunderbar, auch 
ohne die Umwandlung nach String. Nur stimmen dann natürlich die delays, 
die ich benutze, nicht mehr so ganz.

Aber Schuld ist anscheinend der Compiler - nur wie fixe ich das jetzt, 
damit ich auch optimierten Code verwenden kann?

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tja, nur leider hakts jetzt an anderen Stellen, sodass völlig falsche 
Ergebnisse rauskommen.

Das wurmt mich total! Ich schalte mal auf -O1

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Aber Schuld ist anscheinend der Compiler - nur wie fixe ich das jetzt,
>damit ich auch optimierten Code verwenden kann?

Eigentlich kannst du mit 99,99999999999% Wahrscheinlichkeit davon 
ausgehen, daß Berechungen und for-Schleifen mit jeder Optimierungsstufe 
funktionieren. Aufpassen muß man nur mit in Interrupts genutzten 
Variablen, sowie laufzeitabhängigen Codeteilen. Das betrifft dein 
Problem aber nicht.

Der Fehler steckt irgendwo in deinem Code.

Oliver

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Aber Schuld ist anscheinend der Compiler

Schau dir Benedikt's Idee ganz oben an...  ich schließe mich seiner
Meinung an.  Das klingt nach stack overflow.

Autor: kosmonaut pirx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,
kann ich mir bei 4k sram schwerlich vorstellen, aber unmöglich ist 
natürlich nichts.
bye kosmo

Autor: Ronny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Eigentlich kannst du mit 99,99999999999% Wahrscheinlichkeit davon
> ausgehen, daß Berechungen und for-Schleifen mit jeder Optimierungsstufe
> funktionieren.

Nöö...der neue WinAvr scheint es bei höchter Optimierungsstufe an 
einigen Stellen etwas zu übertreiben.Einfach mal hier im Forum suchen...

Und wenn man z.b. in Schleifen Abbruchbedingungen hat,die durch einen 
(Timer-) Interrupt getriggert werden, kann es auch zu 
Laufzeitunterschieden kommen wenn man den Controller Rechenzeit mässig 
an seine Grenzen bringt. Dann reicht mit hoher Optimierung die 
Geschwindigkeit aus, um zur Abbruchbedingung eine Aufgabe in der 
Schleife schon erfüllt zu haben.Mit niedrigerer Optimierung dann unter 
Umständen nicht mehr.

Autor: Uwe ... (uwegw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal simuliert oder die maximale RAM-Belegung gemessen?

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Ronny (Gast)

>Nöö...der neue WinAvr scheint es bei höchter Optimierungsstufe an
>einigen Stellen etwas zu übertreiben.Einfach mal hier im Forum suchen...

>Und wenn man z.b. in Schleifen Abbruchbedingungen hat,die durch einen
>(Timer-) Interrupt getriggert werden, kann es auch zu
>Laufzeitunterschieden kommen wenn man den Controller Rechenzeit mässig
>an seine Grenzen bringt. Dann reicht mit hoher Optimierung die
>Geschwindigkeit aus, um zur Abbruchbedingung eine Aufgabe in der
>Schleife schon erfüllt zu haben.Mit niedrigerer Optimierung dann unter
>Umständen nicht mehr.

Das wage ich zu bezweifeln. Da fehlt dann eher irgendwo ein volatile 
oder es ist ein echter, wenn gleich gut verstecker Programmiefehler.

MFG
Falk

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.