Hallo!! Leider bin ich alles andere als ein GCC Experte. Soweit ich verstehe, enthält das Datensegment initialisierte Daten. Also z.B. die berühmten Stringkonstanten. Obwohl ich meines Wissens alles vermeide, was dort Platz brauchen könnte, werden trotzdem 256 Byte belegt. Auf der Suche habe ich mal einen Blick ins .map File geworfen. .data 0x00800060 0x0 /usr/lib/gcc/avr/4.2.1/avr5/libgcc.a(_pac$ .data 0x00800060 0x100 /usr/lib/gcc/avr/4.2.1/avr5/libgcc.a(_clz$ 0x00800060 __clz_tab .data 0x00800160 0x0 /usr/lib/gcc/avr/4.2.1/../../../../avr/li$ .data 0x00800160 0x0 /usr/lib/gcc/avr/4.2.1/../../../../avr/li$ Ohne wirklich etwas zu verstehen, sieht es so aus, als würde etwas das __clz_tab heisst, die 256 Byte verwenden. Aber was ist das? Vielen Dank! Klaus
Frank B_. wrote: > Siehe hier: > > Beitrag "Winavr20071221 :-(" > > Es ist ein Bug, es gibt aber einen Patch dafür. Na, das fängt ja schön an :-). Egal, vielen Dank für den Hinweis! Wenn ich den Thread aber richtig verstehe, geht es um eine neue Implementierung der floatingpoint lib. In meinem Fall sollte die aber gar nicht verwendet werden. Vermutlich ein Fehler meinerseits. Aber ich verstehe es trotzdem nicht ganz. Es lässt sich auf folgende zwei Zeilen reduzieren: uint8_t l; _delay_ms(l); bindet die library ein, int l; _delay_ms(l); hingegen nicht. int l; _delay_ms((uint8_t)l); aber auch nicht. Ein Blick in avr-libc docu offenbart, dass _delay_ms einen double Wert erwartet. Dass zur Konvertierung von Integer in double die math lib benötigt wird mag sein, aber warum nur bei uint8 und nicht bei int? Liegt das irgendwie am Vorzeichen? Viele Grüße! Klaus
RTFM. Von den Delay-Routinen. Ja, es liegt auch am Vorzeichen, weil genau darin der im Thread beschriebene Bug liegt. Wird aber auch mit Vorzeichen nicht wirklich den gewünschten Erfolg haben.
Ich würde an Deiner Stelle die alte WINAVR-Version (20070525) benutzen, die hat den Bug nicht. Zu dem delay gibts hier irgendwo ein Tutorial, glaube ich. In Kürze: delay_ms und delay_us immer mit Konstanten aufrufen. Frank.
Andreas Kaiser wrote: > RTFM. Von den Delay-Routinen. > > Ja, es liegt auch am Vorzeichen, weil genau darin der im Thread > beschriebene Bug liegt. Wird aber auch mit Vorzeichen nicht wirklich den > gewünschten Erfolg haben. Ich denke ich habe das Manual gelesen und gehe davon aus, dass Du darauf hinaus willst, dass die Routine nur mit Konstanten aufgerufen werden darf, Optimierung usw... Sollte hier eigentlich der Fall sein: void sound(int8_t sound, uint8_t len) { while ( len > 0 ) { _delay_ms(sound); BUZZER_PORT |= bUZZER; _delay_ms(sound); BUZZER_PORT &= ~bUZZER; len--; } } Aufruf z.b. mit: sound(1,4); Ich ging davon aus, dass der Compiler das alles wegoptimiert. So wie es jetzt da steht (int8_t statt uint8_t) funktioniert's auch und es liegt dann wohl doch an dem beschriebenen Bug. Viele Grüße Klaus
Die Delay-Routine muss mit einer Konstanten aufgerufen werden. Was bei dir nicht der Fall ist, denn "sound" ist eine Variable (ein Parameter). Dass der im aufrufenden Quelltext konstant ist, hilft dir nur dann etwas, wenn die Funktion "sound" komplett inlined werden sollte. Dass der Parameter den gleichen Namen hat wie die Funktion, dient wohl in erster Linie der Verwirrung unvorbereiteter Leser? Und dass es mit "int" besser funktioniert als bei "unsigned" liegt in der Tat an dem Bug. Nur wirst du bei genauer Analyse feststellen, dass in dem Aufruf von _delay_ms eine Fliesskommarechnung steckt. Die bei dir zur Laufzeit durchgeführt wird und somit taktfrequenzabhängig das Delay vergrössert. Und zwar egal ob mit oder ohne Vorzeichen, der Unterschied liegt nur darin, welche Fliesskommaruntime verwendet wird. Was du statt dessen machen solltest: for (uint8_t i = 0; i < sound; ++i) _delay_ms(1);
Hallo Andreas! > Die Delay-Routine muss mit einer Konstanten aufgerufen werden. Was bei > dir nicht der Fall ist, denn "sound" ist eine Variable (ein Parameter). > Dass der im aufrufenden Quelltext konstant ist, hilft dir nur dann > etwas, wenn die Funktion "sound" komplett inlined werden sollte. bing klar, jetzt hab ich's begriffen! > Dass der Parameter den gleichen Namen hat wie die Funktion, dient wohl > in erster Linie der Verwirrung unvorbereiteter Leser? :-). Ja, genau! > Und dass es mit "int" besser funktioniert als bei "unsigned" liegt in > der Tat an dem Bug. Nur wirst du bei genauer Analyse feststellen, dass > in dem Aufruf von _delay_ms eine Fliesskommarechnung steckt. Die bei dir > zur Laufzeit durchgeführt wird und somit taktfrequenzabhängig das Delay > vergrössert. Und zwar egal ob mit oder ohne Vorzeichen, der Unterschied > liegt nur darin, welche Fliesskommaruntime verwendet wird. Soweit so klar, aber das heisst bei signed wird die alte, bei unsigned die neue (und mit ihr das rätselhafte __clz_tab) eingebunden (bugbedingt)? Die neue routine ist aber auch im .text Segment fast 1kbyte länger dann. Ok, da sind vielleicht die 256Byte aus dem Datensegment für die Initialisierung dabei? Na, ok, ich glaube diese Probleme lasse ich erstmal die Experten lösen :-). Danke für die Aufklärung! Viele Grüße! Klaus
> Ich ging davon aus, dass der Compiler das alles wegoptimiert. Das tut er auch, aber nur, wenn die Funktion sound immer inline expandiert wird. Du kannst das ezwingen, indem du ihr das __attribute__((always_inline)) mitgibst. Ohne inlining wird der Parameter über ein Register übergeben und kann daher innerhalb der Funktion gar keine Compiletime-Konstante sein. > Die neue routine ist aber auch im .text Segment fast 1kbyte länger > dann. Ok, da sind vielleicht die 256Byte aus dem Datensegment für die > Initialisierung dabei? Ist anzunehmen.
Klaus W. wrote: > Soweit so klar, aber das heisst bei signed wird die alte, bei unsigned > die neue (und mit ihr das rätselhafte __clz_tab) eingebunden Nicht ganz. Es gibt deren drei. Die alte libm/fplib von avr-libc 1.4, die neue libm/fplib von 1.6, und irgendwas obskures generisches in der libgcc. Letztere ist die mit der clz_tab drin, die erwischt es aber nur, wenn irgendwas in der libm/fplib fehlt. Mit Vorzeichen kriegst du also die neue fplib, ohne Vorzeichen die libgcc.
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.