Hallo Zusammen. Ich benutze den WinAVR mit dem eclipse-plugin. Nun hab ich modularisierten code, welcher zum Teil mehrer Aufrufe von Funktionen beinhaltet, welche nur eine weitere aufrufen. z.B. void test(int x){ c(x); } Der compiler übersetzt diesen code logischerweise mit einem einfachen call. und ret. Die Funktion c befindet sich in einem anderen File. und sieh so aus: void c(int x){ b(x); } b() wiederum befindet sich wieder in einem anderen file und macht z.B. void b(int x); PORTA=(char)x; } Befinden sich alle funktionen in einer Datei, so werden alle jumps und calls erwartungsgemäss eliminiert und es bleibt nur noch die Funktion, b() bestehen. Wenn die Funktionen jedoch auf verschiedene Dateien verteilt werden werden die calls und rets nicht weg optimiert. Kann der AVRGCC nicht über mehrere Files optimieren? Wie bringe ich dem Compiler bei, dass er mir solche "sinlosen" calls und rets eliminiert? Die Funktionen müssen auf Grund der Modularität auf verschiedene Dateien aufgeteilt werden. z.B. eine Lib kann eine Linie zeichnen. und diese Funktion soll in eine draw-Lib übernommen (so ähnlich wie bei c++ Vererbung) übernommen werden. die graphs lib greift auf eine draw-Lib und soll ebenfalls die Line function wieder zur Verfügung stellen. Muss ich das mit #defines lösen oder gibt es da eine Möglichkeit das der Compiler das optimiert? Danke für eure Inputs
>Die Funktionen müssen auf Grund der Modularität auf verschiedene Dateien >aufgeteilt werden. Müssen sie? Ich glaube nicht. Dann mach doch einfach ein #include "modulx.c" Würde ich niemals tun, aber wenn es nicht anders geht ;) Das #include "modulx.c" aber nur in einer *.c machen. Der Linker mag es nicht wenn das in mehreren *.c gemacht wird.
> Kann der AVRGCC nicht über mehrere Files optimieren? Nein, das geht prinzipiell nicht. > void c(int x){ > b(x); > } Verlagere die Funktionen, die so aussehen, von der C-Datei in die jeweilige Header-Datei und deklariere sie als static inline. Dann klappt das auch mit den Optimierungen wieder.
Der Grund für diese Sache ist folgender, nun ev gibt es eine besser Möglichkeit: Ich habe eine S1D13700.c, welche eine Line() zur Verfügung stellt. Die BoardsupportLib übernimmt diese und stellt sie als Line() zur Verfügung. Meine draw.c wiederum übernimmt diese Line() von der bslDisplay.c Ich mache das so damit ich nun über die draw.c unabhängig vom Board oder Displaytriber code schreiben kann. z.B. meine chart.c, welche Line() verwendet. Ich will aber nicht für jedes Board oder jedes Projekt eine neue chart.c schreiben. Dass muss ich au nicht, da ich die chart.c für jedes Board verwenden kann, egal welcher Chip oder welches Display drauf sitzt und wie die verbunden sind. Trotzdem will ich eine draw.c haben, welche mir ebenfalls die gleichen Möglichkeiten gibt, und mich direkt auf die Line() Funktion zugreifen lässt, ohne im Code die von der S1D13700.c zu verwenden, den dann ist mein Code nicht mehr unabhängig vom Board. über die draw.c ist er das aber. In meinem Projekt brauche ich nun nur noch die richtigen files über externals einzubinden und mit zu kompilieren und schon habe ich mein Programm. Wechsle ich das board, bleibt der Main code erhalten und ich ändere nur die darunterliegenden libs, binde diese anstelle der anderen ein, compilieren und fertig. So kann ich nun ein Programm schreiben, welches theoretisch auf jedem board laufen kann, wenn die entsprechenden bslDisplay.c da ist. Weiter kann ich die s1d13700.c lib wieder verwenden, für jedes board, wo ein solcher drauf ist. Ich hoffe ihr seht, was ich haben will. Ich sehe für das nur 2 Möglichkeiten. 1. so wie ich das gemacht habe, oder 2. über defines, welche einfach die Line() von der draw auf die Line() von er bslDisplay.c definiert. -> #define Line bslDisplayline Die 2 Variante ist nicht top, weil dadurch die Autocompletion (Content Asisst) von Eclipse nicht mer zurecht kommt. Eigendlich sollte ja der Compiler solcher sachen weg optimieren, aber wenn er nur die einzelnen Files optimiert, dann kann er das nicht. Die Idee ist, dass ich möglichst viel code wiederverwenden kann, unabhänig vom Board und Applikation. (mit momentaner beschränkung auf den AVRGCC)
Nachtrag: natürlich heissen diese Line() nicht in jeder lib gleich s1d13700.h -> s1d13700Line() bslDisplay.h ->bslDisplayLine() draw.h ->drawLine(); in meinem Main code include ich nur noch die "draw.h" meine drawLib. und fertig. Das sollen alles so eine Art Libraries sein.
Und was stört dich an meinem Vorschlag? Oder habe ich dein Vorhaben nur falsch verstanden? Statt: draw.h:
1 | void Line (...); |
draw.c:
1 | void Line (...) { |
2 | bslDisplayline(...); |
3 | }
|
machst du: draw.h
1 | static inline void Line (...) __attribute__ ((always_inline)); |
2 | void Line (...) { |
3 | bslDisplayline(...); |
4 | }
|
Du könntest die Aufrufe auch über den Präprozessor auflösen lassen. "line" existiert nur als #define, das --je nach verwendetem Display-- daraus direkt ein "s1d13700Line" oder entsprechend anders erzeugt.
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.