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
Klingt nach Stackoverflow, irgendein Pointer der iregndwas überschreibt oder sowas in der Art.
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
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.
hallo, soll heissen, wenn du statt
1 | return val |
ein
1 | return 1 |
definierts (und den optimizer ausschaltest), kommt immer noch die endlosschleife? bye kosmo
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
@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.
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?
Tja, nur leider hakts jetzt an anderen Stellen, sodass völlig falsche Ergebnisse rauskommen. Das wurmt mich total! Ich schalte mal auf -O1
>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
> 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.
hallo, kann ich mir bei 4k sram schwerlich vorstellen, aber unmöglich ist natürlich nichts. bye kosmo
> 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.
@ 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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.