Sorry - auf die Gefahr, dass diese Frage schon einmal gestellt wurde? Ich erinnere mich seicht, dass es jenseits von 64 K Flash Probleme in der Adressierung bei den grossen 8bit-ern gibt ... oder verwechsele ich das jetzt ? Nachdem ich mit meinem Programm die Programspeichergrösse 64k überschritten habe, kommen sporadisch immer mehr Laufzeit-Fehler (mit wachsender Programmgrösse). Nachdem ich mal porbeweise die Optimierung ganz ausgeschaltet habe, hängt der Mega 2560 sich nach den ersten Befehlen auf. Bevor ich nun in den Code einsteige, habe ich was prinzipielles nicht beachtet, was man bei der Programmierung eines 256k Flashers beachten sollte ??? Ein Link Hinweis auf die Thematik würde mir schon reichen! ---------------------- AVRSTUDIO zeigt folgende Speichergößen Program: 80788 bytes (30.8% Full) (.text + .data + .bootloader) Data: 3471 bytes (42.4% Full) (.data + .bss + .noinit) EEPROM: 864 bytes (21.1% Full) (.eeprom) ----------------------- Vielen Dank in voraus.
AVRstudio 4.17 Build 666 mit winavr 2009-03-13 und STK500
Der Schalter -Wl,--relax muß angegeben werden. Du mußt mal ins Listung schauen. Wenn alles richtig ist, wird für jede Funktion >64kW ein Trampolin unten angelegt. Ich hatte da allerdings Schwierigkeiten mit printf. Ich hab aber noch nicht untersucht, warum da kein Trampolin angelegt wird, sondern es nach unten verschoben. Für Aufrufe per Funktionspointer (Scheduler) hat das aber geklappt. Peter
Genau genommen benötigt er nur dann für eine Funktion ein Trampolin, wenn irgendwo die Adresse der Funktion verwendet wird. Bei direkten Aufrufen geht es ohne. Wie das der Linker tatsächlich hält ist eine andere Frage.
John Schmitz schrieb: > Program: 80788 bytes (30.8% Full) > (.text + .data + .bootloader) Ne, das isses nich, Du bist ja noch weit unter 50%. > Data: 3471 bytes (42.4% Full) > (.data + .bss + .noinit) Sollte o.k. sein, wenn Du nicht große Arrays local oder per malloc anlegst. Die zählen da nicht mit. Peter
A. K. schrieb: > Genau genommen benötigt er nur dann für eine Funktion ein Trampolin, > wenn irgendwo die Adresse der Funktion verwendet wird. Bei direkten > Aufrufen geht es ohne. Stimmt, nur die Schedulerfunktionen hatten eins. Peter
Peter Dannegger schrieb: > Der Schalter -Wl,--relax muß angegeben werden. > Uppps - der ist schon mal nicht eingestellt. Wo kann ich mehr über Schalter nachlesen ? Was bedeuten die Schalter ? > Du mußt mal ins Listung schauen. Wenn alles richtig ist, wird für jede > Funktion >64kW ein Trampolin unten angelegt. > > Ich hatte da allerdings Schwierigkeiten mit printf. Ich hab aber noch > nicht untersucht, warum da kein Trampolin angelegt wird, sondern es nach > unten verschoben. Witzigerweise habe ich die ersten Probleme bei einem printf in der Ausgabe kommen sehen ...! > > Für Aufrufe per Funktionspointer (Scheduler) hat das aber geklappt. > > > Peter
A. K. schrieb: > Genau genommen benötigt er nur dann für eine Funktion ein Trampolin, > wenn irgendwo die Adresse der Funktion verwendet wird. Bei direkten > Aufrufen geht es ohne. Wie das der Linker tatsächlich hält ist eine > andere Frage. Z.B. hier ?: in Main: { ... extern char *TrainCommand( char *i); ^ | ... TX1Telegram (TrainCommand (RX1Nutzdaten)); // } mit dieser Fuction (die einzige, die ich mit Adresse aufrufe)? char *TrainCommand(char *cmdptr) { ..... }
Nein. Das ist eine normale Funktionsdeklaration und die Funktion gibt ein "char *" zurück. Ich bezog mich auf Code wie
1 | extern char *TrainCommand( char *i); |
2 | char * (*fcnPtr) (char *) = TrainCommand; |
3 | ...
|
4 | ptr = fcnPtr(&c); |
denn darin wird wird dem 16-Bit Zeiger die Adresse der Funktion zugewiesen und diese später indirekt aufgerufen. Während der direkte Sprungbefehl mehrere MB adressieren kann passen in einen 16-Bit Zeiger (auf Funktionen) nur 64KW (=128KB) und mehr als 16 Bits reserviert GCC keinem Zeiger, egel welchem.
Okay, vielen Dank für Eure Hilfe. Dann nehme ich mal meinen Code auseinander ... irgendwo muss das Problem ja stecken. Gottseidank kommt in den Displayausgaben jetzt völliger Strunx, so dass ich mal Testausgaben gestuft einbauen kann, umrauszufinden, wo es denn losgeht. Noch eine Frage: Wo finde ich mal ein umfassendes Tutorial zu den ganzen Schaltern, die beim Compilieren / Linken vorwählen kann? Danke!
das Problem ist wahrscheinlich, das in dieser Compilerversion noch die avr-libc mit der Option -mcallprologues übersetzt wurde. Das führt zu den besagten Problemen mit printf usw. eine einfache Lösung ist eine "kleine" Umlokatierung, wie folgt:
1 | /* for code that needs to reside in the lower 128k progmem */
|
2 | *_unord_sf*.o (.text) |
3 | *_prologue*.o (.text.libgcc) |
4 | *_epilogue*.o (.text.libgcc) |
Einfach ins Linkerfile eintragen ... Aus Performancegründen bietet es sich noch an, alle indirekt aufgerufenen Funktionen auch hier zu plazieren, das spart den Trampoline ... Gruss Frank
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.