Forum: Compiler & IDEs Funktion im Bootbereich aufrufen


von Markus (Gast)


Lesenswert?

Hallo,

ich möchte auf einem ATMega64 aus meinem Programm Daten im Flashspeicher 
ablegen.
Die Software selber soll mittels Bootloader übertragen werden.
Um nun aus dem Hauptprogramm Daten ins Flash zu schreiben muss sich die 
flash-write Funktion ja im Bootloader Bereich befinden. (d.h. hinter der 
mittels BOOTSZ0 und BOOTSZ1 festgelegten Bootloaderadresse liegen)
Daher habe ich die funktion wie folgt definiert:
1
void __attribute__ ((section (".pmBoot"))) writeFlashPage(uint32_t pagestart, uint16_t *Dataptr) {...}
und die section im Makefile hinter den Bootloader verschoben.

Dies Funktioniert hier auch so inkl. Bootloader, nur AVRProg meckert 
natürlich an das im Bootloader bereich geschrieben werden soll und ich 
kann diesen daher ja auch nicht schützen.

Nun möchte ich diese writeFlashPage funktion im Bootloader integrieren 
und aus den Hauptprogramm darauf zugreifen.

Leider weis ich jetzt nicht wie ich dieses hin bekomme. Mein Versuch mit
1
void (*writeFlashPage)(uint32_t pagestart, uint16_t *Dataptr) = 0x00fe00;
funktioniert so leider nicht.

kann mir jemand hier weiterhelfen?

Danke und Gruß

Markus

von Stefan E. (sternst)


Lesenswert?

Markus wrote:

> Leider weis ich jetzt nicht wie ich dieses hin bekomme. Mein Versuch mit
1
void (*writeFlashPage)(uint32_t pagestart, uint16_t *Dataptr) = 0x00fe00;
> funktioniert so leider nicht.

Was genau bedeutet "funktioniert nicht"?

Du müsstest als Adresse natürlich auch die genaue Adresse der Funktion 
eintragen, und nicht die Startadresse des ganzen Bootloaders.

von Markus (Gast)


Lesenswert?

Hi,

0x00fe00 ist die Adresse in der die Section .pmBoot liegt, in der nur 
die Funktion writeFlashPage(..) liegt.

im Makefile so angeben:
EXTMEMOPTS 
=-Wl,--section-start=.pmData=0x002500,--section-start=.pmBoot=0x00fe00

Ich habe jetzt im ersten versuch das Programm mit der integrierter 
Funktion per bootloader übertragen.
-> Funktion ok.
dann in dem Programm die Funktion durch
1
void (*writeFlashPage)(uint32_t pagestart, uint16_t *Dataptr) = 0x00fe00;
 ersetzt und erneut peer bootloader übertragen.
Die Funktion im Bootbereich wird dabei ja nicht überschrieben und ist 
auch noch vorhanden (ich habe zur Überprüfung das Flash ausgelesen)

Jetzt bleibt das Programm beim Zugriff auf die Funktion hängen und 
startet irgentwann neu (obwohl der WDT noch nicht aktiviert ist)

Mir ist jedoch aufgefallen das die .text section im zweiten Fall 24 Byte 
grösser ist, ich hätte ja erwartet das sich hier nichts ändert.

von Stefan E. (sternst)


Lesenswert?

Du widersprichst dir. Was genau hast du denn nun im Bootloaderbereich, 
nur die Funktion oder einen kompletten Bootloader, der die Funktion 
enthält?

von Markus (Gast)


Lesenswert?

Im Bootbereich liegt der bootloader plus diese Funktion die vom 
"normale" Programm aus genutzt werden soll.
Diese Funktion liegt in einer eigenen Section ab 0x00fe00, damit ich 
eine definierte Adresse für die Funktion habe.

von Stefan E. (sternst)


Lesenswert?

Ok, der Bootloader liegt also vor der Funktion.

Wahrscheinlich rechnet der Compiler bei direkten Zuweisungen an einen 
Funktionspointer den Wert nicht um. Du musst ihn also selber durch 2 
teilen.

Alternativ kannst du die Funktion extern deklarieren und dem Linker die 
Adresse über die Kommandozeile mitteilen. Dann wirst du die zusätzlichen 
24 Byte auch wieder los.

von Markus (Gast)


Lesenswert?

ja das war es
1
void (*writeFlashPage)(uint32_t pagestart, uint16_t *Dataptr) = (0x00fe00/2);

funktioniert!

Danke, danke!

und wie kann ich alternativ dem Linker die Adresse mitteilen?

Danke und Gruß

Markus

von Stefan E. (sternst)


Lesenswert?

> und wie kann ich alternativ dem Linker die Adresse mitteilen?

-Wl,--defsym=writeFlashPage=0xfe00

(Hier aber die Byte-Adresse)

von mar (Gast)


Lesenswert?

Oder noch diese Alternative, funktioniert auch:

Header-File:
1
typedef void (*writeFlashPage_fn_ptr_t)(uint32_t pagestart, uint16_t *Dataptr);
2
3
#define writeFlashPage(pagestart, Dataptr)   ((writeFlashPage_fn_ptr_t)(0x00fe00/2))(pagestart, Dataptr)

Damit ist es nicht erforderlich, einen Pointer anzulegen, da die Adresse 
in die entsprechend typisierte Funktion gecastet wird.

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.