Forum: Mikrocontroller und Digitale Elektronik ATmega256 Trampolin-Problem


von Rangi J. (rangi)


Lesenswert?

Hallo Forum,
ich verwende eine ATmega256 und Atmel Studio. Ich möchte den Flash aus 
meiner Applikation schreiben. Dazu habe ich einige einfache Funktionen, 
die in der BSL-Section abgelegt sind und von meiner Appliaktion gerufen 
werden. Um bei unterschidlicher Codegröße oder anderen Versionsständen 
dieser Funktionen immer den richtigen Einsprungpunkt zu finden, verwende 
ich void-Pointer (für jede Funktion einen), die in einer eigenen Section 
ganz am Ende des BSL liegen.
Damit kann sich der Code der Flashroutinen ändern, werden aber trotzdem 
von allen Applikationen korrekt angesprungen.
Jetzt das Problem: Bei Sprüngen zum Flash > 64k wird ein Trampolin 
gelinkt, welcher dann vor meinen Pointern liegen. Ich lade mit 
pgm_read_dword... nicht mehr meine Adresse in der BSL-Section sondern 
die Adresse im Trampolin. Das macht natürlich keinen Sinn, denn der 
Trampolin ändert sich im Vergleich zum BSL.
Was gibts denn da für eine Lösung?

Hier als Beispiel ein ausschnitt aus der Header-Datei:
1
typedef void (*BOOT_tvfv)(void);   /*Typedef für Funktionen void (void)*/
2
3
extern const BOOT_tvfv BOOT_fpEraseShadow;   /*Funktionszeiger - liegt in der .bootfunctab section*/
4
5
/*dieses makro wird in der Applikation verwendet*/
6
#define BOOT_CALL_ERASE_SHADOW()   \
7
do { \
8
  BOOT_tvfv f=(BOOT_tvfv)pgm_read_dword_far(&BOOT_fpEraseShadow);  \
9
  f(); \
10
} while(0); \

von Stephan B. (matrixstorm)


Lesenswert?

Hallo Rangi Jones.

Das ist das gleiche Problem wie in 
https://github.com/baerwolf/USBaspLoader/blob/testing/firmware/spminterface.h.
USBaspLoader unterstuetzt eine API, die auch das Schreiben im Flash 
erlaubt.
spminterface.h stellt dazu die noetigen USER-Funktionen bereit.
(Diese sind getestet und fuktionieren, Vielleicht moechtest du ja auf 
diese Funktionen in Zukunft umsteigen?)
Eine Demonstrationsimplementierung schrieb ich in 
Beitrag "Re: [ATMega] Programm aus externem EEprom laden"

Zu deinem Problem:
Ansonsten musst du manuell das EIND Register fuer indirekte Spruenge 
anpassen - normale C-Funktionszeiger funktionieren nicht ueber die 
128Kib Barriere hinaus: 
http://gcc.gnu.org/onlinedocs/gcc/AVR-Options.html#index-g_t_0040code_007bEIND_007d-1260
Normale Zeiger sind beim AVR nur 16Bit breit.

Eigentlich fuer ATxmega habe ich mir ein Wrapperinterface gebaut, 
welches das Sichern und Modifizieren von EIND fuer mich automatisch 
vornimmt, sodass ich einigermassen bequem (erweiterte) Funktionszeiger 
benutzen kann.
Auf Wunsch werde ich die Datein etwas aufraeumen und ein kleine Beispiel 
vorbereiten. Sobald das getan, kann ich die Dateien fuer dich hier ins 
Forum legen...

Fuer Fragen stehe ich dir gern zur Verfueung.

MfG Stephan

: Bearbeitet durch User
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.