Hi, mein Code ist etwas umfangreicher geworden, so dass er nicht mehr auf den Chip passte. Mit Optimierung auf höchster Stufe spare ich 50% Memory ein, aber meine Wartefunktionen aus der delay.h sind jetzt viel schneller und warten nicht die gewünschte Zeit. Kann ich irgendwie dem Compiler sagen, dass er bei der delay.h und ihren Funktionen nichts Optimieren soll?
AVR-GCC (WINAVR)? Es gab mal ähnliche Probleme, allerdings 2007. Und eine so alte Tolchain setzt du nicht ein, oder? Den offensichtlichen Fehler hast du bestimmt auch nicht gemacht - die delays ohne Optimierungsstufe zufällig passend zu einem falsch eingestellten Takt und jetzt mit irgendeiner Optimierung sind sie zu schnell. Wenn du ein nachvollziehbares Beispiel (Minisource und mehr Angaben zur Toolchain inkl. Optimierungsstufe) hast, kann vielleicht jemand der Sache nachgehen. An das Disassemblat bist du wohl noch nicht rangegangen, um zu sehen, ob der delay-Code noch im Programm vorhanden ist. Kannst du auch mal machen. Auch wäre es hilfreich, wenn du den Beschleunigungsfaktor ermitteln kannst - 4x so schnell wäre ein sehr verdächtiger Wert für eine bestimmte Toolchain mit defektem delay. Ich hoffe man sieht bereits etwas im Simulator, ansonsten bräuchte man auch noch Angaben zur Schaltung.
rubbellos schrieb: > Mit Optimierung auf höchster Stufe spare ich 50% Memory > ein, aber meine Wartefunktionen aus der delay.h sind jetzt viel > schneller und warten nicht die gewünschte Zeit. > > Kann ich irgendwie dem Compiler sagen, dass er bei der delay.h und ihren > Funktionen nichts Optimieren soll? Das ist eher ungewöhnlich, denn eigentlich ist für die delay-Funktionen die Optimierung notwendig. Die Delays stimmen nur bei eingeschalteter Optimierung.
rubbellos schrieb: > Kann ich irgendwie dem Compiler sagen, dass er bei der delay.h und ihren > Funktionen nichts Optimieren soll? Ganz im Gegenteil! Wenn du in der delay.h nachliest, steht da geschrieben: "In order for these functions to work as intended, compiler optimizations must be enabled, and the delay time must be an expression that is a known constant at compile-time." Kennt deine delay.h die richtige CPU-Frequenz und verwendest du die aktuelle delay-Bibliothek?
Da er über die Auswahl des Forums grad mal nahegelegt hat, dass es sich um den GCC handeln dürfte, nicht aber für welche Architektur, sollte man evtl. abwarten, bis er mehr darüber verrät.
bis dahin kann man ja mal wieder raten :-) Ich tippe auf Nichtkonstanten beim Aufruf.
Benutze AVR Studio 5 mit AVR GCC. Hab nur #indlude <avr/delay.h> geschrieben und dann mit _delay_ms(200) aufgerufen.
Sie sind schneller, ja. Aber davor waren sie langsamer als du eigentlich erwartet hast. Übrigends ist es jetzt <util/delay.h>
rubbellos schrieb: > Mit Optimierung auf höchster Stufe Alles ausser -Os ist bei einem AVR selten sinnvoll. Oliver
Oliver schrieb: > Alles ausser -Os ist bei einem AVR selten sinnvoll. Wenn man genügend freien Flash hat, kann man das Programm mit -O3 sauschnell bekommen. ;-)
Jörg Wunsch schrieb: > Wenn man genügend freien Flash hat, kann man das Programm mit -O3 > sauschnell bekommen. ;-) Was ist denn sauschnell? Schleifen aufdröseln spart gerademal DEC+BRNE (3 Zyklen) pro Durchlauf. Das ist lächerlich wenig und völlig unmerkbar. Peter
Peter Dannegger schrieb: > Was ist denn sauschnell? Hängt natürlich immer vom Umfeld ab, aber bis zu 2:1 habe ich schon erlebt. Allerdings hat man reichlich selten wirklich Zeitprobleme auf einem AVR.
Peter Dannegger schrieb: > Was ist denn sauschnell? Beispielsweise - Agressiveres Inlining kann Berechnungen erheblich eindampfen, wenn aus Parametern Konstanten werden. - Duplizierung von Schleifen, um invariante Bedingungen rauszuwerfen.
Klaus Wachtler schrieb: > bis dahin kann man ja mal wieder raten :-) > Ich tippe auf Nichtkonstanten beim Aufruf. Ich tipp auf Optimizer aus, gepaart mit: Oooch, die delays. Da probier ich jetzt einfach ein paar Zahlenwerte durch, bis es mir passt. Was schert mich ob 500 Millisekunden auch 500 Millisekunden sind, das Ergebnis muss passen. Und jetzt ist der Optimizer ein, 500 ms sind auch wirklich ca. 500 ms. Und das Geschrei ist groß, dass die mühsam durch Versuch und Irrtum angepassten Delay-Zeiten nicht mehr brauchbar sind.
Karl Heinz Buchegger schrieb: > Und jetzt ist der Optimizer ein, 500 ms sind auch wirklich ca. 500 ms. Vielleicht sind es jetzt ja auch 62,5 ms. ;-)
Gibt es keine Präprozessor Befehle mit denen man den Teil der nicht optmiert werden soll einklammern kann? Sowas wie:
1 | #dont_optimizize
|
2 | code
|
3 | #end_dont_optimizize
|
rubbellos schrieb: > Gibt es keine Präprozessor Befehle mit denen man den Teil der nicht > optmiert werden soll einklammern kann? Jein. erstens macht das nicht der Präprozessor. Der macht nur Textersetzungen und optimiert nicht. Als #pragma/Funktionsattribut geht das. => GCC dokumentation lesen. aber Vorher: Wenn du sowas brauchst, ist es ein fast 100%iges Zeichen dafür, dass dein Programmcode FALSCH ist. Behebe lieber die Fehler, anstatt an den Symptomen rumzudoktorn.
rubbellos schrieb: > Gibt es keine Präprozessor Befehle mit denen man den Teil der nicht > optmiert werden soll einklammern kann? Der Präprozessor? Der optimiert noch gar nichts. Ja, es gibt in neueren GCC-Versionen pragmas dafür. Nein, die brauchst du nicht. Du versuchst gerade, eine Kopfschmerz- tablette zu nehmen, statt die Ursache der Kopfschmerzen zu beseitigen. Ja, ich weiß, dass diese Art der "Krankheitsbekämpfung" modern ist, aber du tust dir damit keinen Gefallen. Weder bei den Kopfschmerzen noch bei den delays.
Das ist IMHO der falsche Ansatz so lange die Ursache noch unbekannt ist. Um deine Neugier zu stillen: Erst GCC ab Version 4.4 (also nicht für WinAVR2010... inklusive! Aber möglicherweise mit der Atmel AVR Toolchain) bietet ein #pragma zur Einstellung von Optimierungen auf Funktionsebene an (http://gcc.gnu.org/onlinedocs/gcc/Function-Specific-Option-Pragmas.html#Function-Specific-Option-Pragmas).
Das wird aber alles gar nichts bringen. Der Grund für das Einschalten der Optimierungen war ja der zu große Flashbedarf. Ein mit ziemlicher Sicherheit erheblicher Teil dieses Flashbedarfs resultiert aber aus de Nutzung der Delay-Funktionen ohne Optimierung. Wenn er also jetzt die Optimierungen gezielt nur für die Delays ausschaltet, wird auch der Flashbedarf wieder stark ansteigen. Es wird also nichts anderes übrigbleiben, als die die bisher falsch eingestellten Delay-Zeiten zu korrigieren.
Suche nach Gcc Function Attributes...dort gibt es folgendes: optimize The optimize attribute is used to specify that a function is to be compiled with different optimization options than specified on the command line. Arguments can either be numbers or strings. Numbers are assumed to be an optimization level. Strings that begin with O are assumed to be an optimization option, while other options are assumed to be used with a -f prefix. You can also use the `#pragma GCC optimize' pragma to set the optimization options that affect more than one function. See Function Specific Option Pragmas, for details about the `#pragma GCC optimize' pragma.
Dante schrieb: > Suche nach Gcc Function Attributes...dort gibt es folgendes: > optimize Maaahaaa! Nein, tue es bitte nicht. siehe Posts hier vor. Code her, alles Andere ist Murks und keine richtige Lösung.
Yo Simonsen haste Recht. Hab mich verlesen, "compiler optimization must be turned ON". Wenn es mit util/delay.h nicht funzt dann schreibs halt selber. Inline Assembler, mit #if die Anzahl von Nops vom Takt abhängig machen und gut ist.
UND DANN optimierung für die delay-Funktion abschalten ;)
Dante schrieb: > Inline Assembler, mit #if die Anzahl von Nops vom Takt abhängig machen > und gut ist. Schon hast du <util/delay.h> wiedererfunden. ;-) OK, NOPs werden eher nicht benutzt, man bräuchte für 200 ms auch ziemlich viele. <util/delay_basic.h> für die, die sich die Anzahl der Zyklen lieber selbst ausrechnen möchten.
dann werf die delays weg und nimm nen timer ^^ abgesehen von irgendwelchen einschaltdelays hab ich bisher nie die delay dinger gebraucht und da tut es auch ein for(xxx); mit einer lokalen volatile die nach der init im nirvana verschwindet
fdssd schrieb: > und da tut es auch ein for(xxx); mit einer lokalen volatile > die nach der init im nirvana verschwindet Soso. Und wie gebe ich dann die Dauer an? Die delay.h funktioniert einwandfrei, wenn man folgende Sachen beachtet: - nicht die alte von AVRStudio5 nehmen (4-mal zu schnell) - Vorher F_CPU definieren - Optimierung: "-Os" Peter
fdssd schrieb: > hab ich bisher nie die delay > dinger gebraucht Für sehr kurze Verzögerungen (wie man sie bspw. beim Ansteuern von LC-Displays hat) lohnt sich oft das Anwerfen eines Timers gar nicht. Für 200 ms ist das natürlich was anderes.
Peter Dannegger schrieb: > Die delay.h funktioniert einwandfrei, wenn man folgende Sachen beachtet: > - nicht die alte von AVRStudio5 nehmen (4-mal zu schnell) kannst du dafür einen Link geben? ich krieg die Worte "alt" und "von Studio5" nicht zusammen.
Vlad Tepesch schrieb: > ich krieg die Worte "alt" und "von Studio5" nicht zusammen. Die AVR Toolchain, die mit AVR Studio 5 direkt ausgeliefert wird, hat eine buggige Version der avr-libc erwischt, in der die delay-Routinen 4mal zu schnell waren (mea culpa). Ich glaube, es gibt mittlerweile von Atmel eine neue Version der AVR Toolchain, die eine neuere Version der avr-libc mitbringt.
Jörg Wunsch schrieb: > OK, NOPs werden > eher nicht benutzt, man bräuchte für 200 ms auch ziemlich viele. schonmal was von Schleifen gehört. Btw durch den bedingten Sprung braucht man noch weniger NOPs ;)
Dante schrieb: > schonmal was von Schleifen gehört. Btw durch den bedingten Sprung > braucht man noch weniger NOPs ;) Du bist so kluk. Nun warum genau braucht man jetzt NOPs in den Schleifen? Achja, ein bedingten Sprung verbraucht ja keine Zeit, das tun nur die NOPs...
danke Klaus du .... aber mal im Ernst: Jörg hat ja recht, es wäre ein Remake von delay.h, aber stört es euch nicht dass die Include-Datei zwingend -Os fordert? Wenn es anders herum wäre würde es mir eher einleuchten (also eine delay.h die ohne Optimierung kompiliert werden müsste). Ob man jetzt nur ne Schleife macht und die Zyklenanzahl vom Takt abhängig ist oder Noppels in der Schleife vom Takt abhängig...das schenkt sich ja nix.
Jörg, warum braucht delay.h die Einstellung -Os ????
Dante schrieb: > Jörg, warum braucht delay.h die Einstellung -Os ???? Weil es die nutzerfreundliche Variante von <util/delay_basic.h> ist. Bei dieser muss man alles selbst ausrechnen, delay.h will dem Nutzer die Arbeit abnehmen. Zur Nutzerfreundlichkeit gehört für mich dazu, dass man eben auch _delay_ms(2.5) angeben kann, genauso wie #define F_CPU 3.68E6 (denn auf dem Quarz steht 3.68 MHz, nicht 3680000 Hz drauf). Die Zahlen, die man als Ingenieur für gewöhnlich benutzt, sind nun einmal in aller Regel Gleitkommazahlen. Warum soll ich denn meinen Kopf verbiegen, wenn der Compiler das stattdessen tun kann? Wer nicht optimiert, braucht ohnehin keine delays. :-) Ich verstehe einfach bis heute nicht, warum man bei einem Prozessor wie dem AVR (der ziemlich RISC ist von der Art und Weise, wie die Befehle gebaut sind) freiwillig auf die Optimierungen des Compilers verzichtet.
Wer die Freuden des Debuggings per IDE und Simulator/JTAG/DW wirklich geniessen will, der muss da manchmal durch. Nicht jeder kann sich mit dem wirren Gehüpfe durch optimierten Code wirklich anfreunden, oder kapiert auch nur warum das so seltsam läuft und Variablen sich so seltsam benehmen. Und dann sind da natürlich noch jene, deren Code optimiert nicht läuft, was selbstverständlich nur am Compiler liegen kann. ;-)
Ok Jörg, das sehe ich ein. Schließlich will nicht jeder Atmega-Neuling Takte abzählen. Da ich eher Informatiker als Ingenieur bin bevorzuge ich diskrete Zahlen statt Floating, aber jedem das seine. Jörg Wunsch schrieb: > Wer nicht optimiert, braucht ohnehin keine delays. :-) Ein netter Scherz, aber du vergisst es soll ja sogar (zeitkritische) Routinen geben soll, die KEINE smart optimization wollen. Oder abgefahrene (wenn auch zugegebenermaßen bestimmt sehr seltene) Projekte, in denen der Schreiberling sich nicht die Asm-Instruktionen vom Compiler durcheinanderwürfeln lassen mag. Aber für den Otto-Normal-AvrLib-User und in fast 100% aller Fälle hast schon recht.
Dante schrieb: > Ok Jörg, das sehe ich ein. Schließlich will nicht jeder Atmega-Neuling > Takte abzählen. Da ich eher Informatiker als Ingenieur bin bevorzuge ich > diskrete Zahlen statt Floating, aber jedem das seine. Du kannst ja auch jederzeit die angesprochenen delay_basic.h-Funktionen verwenden. Die kommen ganz ohne Gleitkommarechnung und F_CPU aus. Dafür muß man eben selbst ausrechnen, wieviele Schleifendurchläufe man für die gewünschte Delay-Zeit braucht. > Jörg Wunsch schrieb: >> Wer nicht optimiert, braucht ohnehin keine delays. :-) > > Ein netter Scherz, aber du vergisst es soll ja sogar (zeitkritische) > Routinen geben soll, die KEINE smart optimization wollen. Wenn sie so zeitkritisch sind, müssen sie sowieso in Assembler geschrieben werden, und da wird nix mehr optimiert. C-Code so hinzufrickeln, daß das Timing so exakt paßt, ist Murks und wird einem spätestens bei der nächsten Compiler-Version oder auch nur irgendeiner Änderung der Optionen nach hinten losgehen. > Oder abgefahrene (wenn auch zugegebenermaßen bestimmt sehr seltene) > Projekte, in denen der Schreiberling sich nicht die Asm-Instruktionen vom > Compiler durcheinanderwürfeln lassen mag. Auch dann muß er sie in Assembler schreiben.
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.