Forum: Compiler & IDEs Volle Adressierbarkeit (256k) im Programmspeicher bei Mega 2560 ?


von John S. (student)


Lesenswert?

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.

von Walter T. (nicolas)


Lesenswert?

Welchen Programmer nutzt Du?

von John S. (student)


Lesenswert?

AVRstudio 4.17 Build 666 mit winavr 2009-03-13 und STK500

von Peter D. (peda)


Lesenswert?

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

von (prx) A. K. (prx)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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

von John S. (student)


Lesenswert?

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

von John S. (student)


Lesenswert?

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)
{

.....

}

von (prx) A. K. (prx)


Lesenswert?

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.

von John S. (student)


Lesenswert?

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!

von Frank (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.