Volle Adressierbarkeit (256k) im Programmspeicher bei Mega 2560 ?

OP #1690144
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.
#1690165
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
OP #1690195
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
OP #1690204
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)
{

.....

}
#1690254
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.
OP #1690308
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!
Gast #1690928
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren