Funktion im Bootbereich aufrufen

Gast #1007668
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
#1007681
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.
Gast #1007704
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.
Gast #1007737
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.
#1007746
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.
Gast #1007759
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
Gast #1007858
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.

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