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
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.
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?
>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.
> 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