Hi @ all,
ich habe ein kleines Problem wo mir ein erfahrener AVR C Programmierer
bestimmt weiter helfen kann.
Ich rufe folgende Funktion...
void gen_hl() {
PORTD = 127;
}
...mit...
gen_hl();
...auf.
Solange man den Optimierungs-Schalter auf -O0 (Ohh null) läst geht das
auch alles. Stellt man um auf -Os was ja empfohlen wird dann ist der
Optimierer aber fleißig... zu fleißig, er ruft die Funktion erst
garnicht mehr auf... warum?
Gruß Frank
Hast du nachgesehen, ob die Funktion ge"inlined" wird?, d.h. der
Compiler setzt die Anweisung in der Funktion direkt ins Programm ein,
anstatt die Funktion aufzurufen.
Danke für die schnellen Antworten,
also (void) bringt nichts, das "komische ist, es läst sich noch nicht
einmal ein Breakpoint setzen. Deutet wohl darauf hin das er es völlig
ignoriert.
>> Hast du nachgesehen, ob die Funktion ge"inlined" wird?, d.h. der>> Compiler setzt die Anweisung in der Funktion direkt ins Programm ein,>> anstatt die Funktion aufzurufen
Ähm ok, was bedeutet das?
Wo würde man das sehen, was ist zu tun?
Gruß Frank
> Ähm ok, was bedeutet das?
wenn die Anweisung ausgeführt wird, die in der Funktion steht, ist es
doch egal.
> Wo würde man das sehen, was ist zu tun?
Sieht man im list-file (da stehen die Assemblerbefehle drin, aus denen
das Prog im Endeffekt besteht
Jo ok,
also da sieht es tatsache nicht so aus als ob es angesprungen wird.
Ich verstehe auch ASM, wollte aber nun ein Programm in C schreiben.
Geht das nicht in C das man eben wiederkehrende Sachen in eine Funktion
legt?
Hmm hat noch jemand einen Tip warum es wohl wegoptimiert wird?
Wie würdet ihr eine Funktion beschreiben?
Das GCC Tour in dem Forum habe ich gesehen, das mache ich eigendlich so.
Verwende AVR Studio und WinAVR.
Gruß Frank'l
PORTD als volatile deklarieren? Wie geht denn das? ;)
Und was "void" in den Klammern bringen soll, ist mir auch schleierhaft.
Warum sollte er den Ausdruck nicht als Funktion erkennen?
Woher nimmst du die Information, dass die Funktion nicht aufgerufen
wird?
PS: Schau doch mal in dem Listfile (*.lst) nach, ob die Funktion
aufgerufen/inlined wird.
>> Hmm hat noch jemand einen Tip warum es wohl wegoptimiert wird?
weil der AUfruf (Rcall + push(evtl.) + ... pop + ret) länger
dauert("teurer ist") als die eigentlich Funktion (ldi + out), wenn du
eine längere Funktion schreibst oder die Funktion in eine andere
"compilation-Unit" (.c-Datei) auslagerst, wird die nicht ge-"inlined".
Da PORTD garantiert als "volatile" deklariert ist, wird es gcc mit
Sicherheit nicht wegoptimieren.
Wenn es Dir im ASM-Quelltext nicht über den Weg läuft, hast Du es
bestimmt übersehen...
Probiere doch einfach mal, so ein minimal-Programm zu flashen, um Dir
dann den PORT über ein Oszi anzuschauen.
Wenn es dann nicht geht, hat Dein uC vielleicht gar keinen PORTD (kommt
gerne mal vor, daß soetwas übersehen wird)...
Hallo nun ich hab mal den Code auf ein Mininmum reduziert, wie gesagt
die -O Option ist auf -Os um den "schnellsten" Code zu erzeugen.
gen_off(); Wird nicht angesprungen... :-(
µC ist ein ATmega16 auf'n STK500 mit AVR Studio und WinAVR.
Hallo digifloh,
zeig doch mal die .lst-Datei. Bestimmt ist die Funktion in diesem Fall
geinlined worden, weil es dann einfach schneller geht. Solange die
Wirkung aber diesselbe ist, sollte es eigentlich egal sein, ob die
Funktion angesprungen wird oder nicht. Übrigens: -0s erzeugt nicht den
schnellsten sondern den kleinsten Code. -03 erzeugt den schnellsten
Code, in den meisten Fällen aber auch den größten.
MfG Mark
Meinst du nicht, dass das ein bischen an den Haaren herbeigezogen ist,
das Programm, das du gepostet hast tut (im Simulator) genau was es soll,
PORTD wird vorher schon gesetzt, und die struct wird extra gesetzt.
Demnach meint der gcc dass sich der Aufruf nicht rechnet (da hat der
sicher recht).
Du hast eine bessere chance eine Funktion zu beobachten wenn diese
Parameter übernimmt oder werte zurückgibt. (und es gibt ein no_inline_
oder so änhlich -attribute und enstprechende GCC-Parameter, um die zu
nutzen müsstest du allerdings das GCC-Manual lesen ...
hth. Jörg
Hallo!
Ich weis zwar nicht was fuer ein Prozessor es ist, aber das kommt mit
spanisch vor......
PINB = 0; // Pullups off
Ich denke die Zeile tut nicht das was als Kommentar da steht....
gruß,
Bjoern
Ich habe das letzte Programm mal durch den gcc gejagt.
'gen_off()' wird ge-inlined, die Funktion selbst ist
aber da. Sie wird halt nur nicht aufgerufen.
Die Funktion muß der Compiler auch erzeugen weil er nicht
wissen kann ob sie nicht von einem anderen Modul aus
aufgerufen wird.
Mit 'static' deklariert nimmt er sie aber raus.
Da habe ich gerade etwas dazugelernt: Ich dachte bisher immer
das der gcc nur mit -O3 inlining benutzt - abgesehen von statischen
Funktionen die nur einmal verwendet werden. Mit -O{0,1,2} wird die
Funktion aufgerufen.
- Michael
@Jorg X.
Sicher ist es ein Programm was nur als Beispiel dient aber nicht
unnöglich ist.
Beim START möchte ich einmal die Funktion aufrufen, das ist alles, ich
gehe mal davon aus das es total egal ist was man da reinschreibt in der
Funktion. Ob nun 150 ein A über den UART ausgegeben wird oder einfach
nur der Wert 127 am PortD.
Kann es an meiner Timer Ini liegen?
Die lss Datei hab ich mal angehangen...
MfG Frank'l
Es ist nicht egal, was in der Funktion drinsteht, solange der Compiler
das weiß! -> wenn du die Funktion in eine andere .c-Datei schreibst,
wird die auch aufgerufen, weil der Compiler nicht inlinen kann, und
glaub mir, wenn inlinen keine Vorteile bringt wird der compiler es auch
ganz lassen.
Können wir diese "Diskussion" fortsetzen, falls der GCC so inline't,
dass das Programm nicht mehr funktioniert?
Hallo,
@Joerg X.
Ja war vlt. etwas übertrieben, ich wollte nur sagen das es für das
Verständniss Funktionen halt egal wäre was im eigendlichen in ihr steht.
Vielleicht wäre eine For Schleife besser... ;)
Ok Knackpunkt ist das inline, das wußte ich nicht.
Ich habe nun mal das prg Step für Step im Deassembler durchgeklickert...
es macht inline wie du richtig angenommen hast...
Also muß mein Fehler woanders liegen, ich hab was gelernt und sogar
verstanden was :-D
Das nächste mal wenn sich ein Punkt nicht anspringen läst schau ich hier
als erstes nach.
Dank euch... schönen Sonntag...
>Ok Knackpunkt ist das inline, das wußte ich nicht.
Der Knackpunkt ist nicht das inline, sondern, daß der gcc, genauso, wie
andere Compiler auch, bei eingschalteter Optimierung Code erzeugt, der
nicht mehr 1:1 rückwärts dem C-Quelltext zugeordnet werden kann. Das
macht der nicht nur durch inlining, da gibt es noch viele andere
"Schweinereien" :-)
Fazit:
Wenn du deinen Sourcecode Zeile für Zeile durchsteppen möchtest, geht
das nur mit -O0. Andere Compiler verbieten von vorherein, Debuginfos für
optimierte Programme zu erzeugen, der gcc ist da etwas großzügiger.
Oliver