Forum: Compiler & IDEs Daten im Flash an bestimmter Adresse speichern


von Stefan T. (stefan90)


Lesenswert?

Hallo,

ich programmiere gerade einen Bootloader für einen ATmega128 und 
verwende zusätzlich ein Statusbyte, das im Flash abgespeichert wird. 
Dieses soll wenn möglich an letzter Stelle im Flash - beim mega128 also 
an 0x1FFFF - stehen.

Doch wie kann ich das dem GCC sagen?
Wenn ich
1
uint8_t PROGMEM status = 0x10;
schreibe, dann weiß ich ja nicht exakt wo das Byte abgelegt wird. Da ich 
dieses Byte wieder verändern muss (nach jedem neuem Flashen der 
Hauptapplikation), weiß ich jetzt nicht welche Page in der 
Bootloadersection selbst ich neu beschreiben muss. Bei der letzten 
Adresse im Flash hab ich das Problem nicht, da lies ich einfach immer 
die letzte Page aus, verändere mein Statusbyte und schreibe die Page 
neu.

In Assembler würde ich das Statusbyte einfach so ablegen:
1
.org FLASHSIZE/2
2
status: .db 0x10
Geht das auch irgendwie in C? Was passiert wenn ich das so in Inline 
Assembler hinschreibe?

Was allgemeines: in der pgmspace.h wird empfohlen, Daten im Flash 
generell in unteren 64k abzulegen. Kann mir jemand sagen warum? Ich kann 
es ja nicht beeinflussen, wenn ich
uint8_t PROGMEM status = 0x10;
schreibe, wo der GCC dieses Byte ablegt oder?

mfg Stefan

von Stefan T. (stefan90)


Lesenswert?

Zum Thema Byte an konstanter Adresse abspeichern hab ich leider zuvor 
folgenden Beitrag übersehen Beitrag "[AVRGCC] Konstante an fest definierte Adresse im Flash"

Kann mir jemand sagen wie ich das aber genau nutze?

mfg Stefan

von Kai G. (runtimeterror)


Lesenswert?

>Was passiert wenn ich das so in Inline
>Assembler hinschreibe?

hmm... ausprobieren geht wahrscheinlich am schnellsten ;)

Lesende Zugriffe auf's Flash werden mit LPM oder ELPM durchgeführt. Per 
LPM ist's minimal schneller, da RAMPZ nicht initialisiert werden muss.
Siehe ELPM-Code-Beispiel (Seite 68):
http://www.atmel.com/dyn/resources/prod_documents/doc0856.pdf
Gegenüber dem LPM-Beispiel auf Seite 91. LPM kann halt nur die unteren 
64 k adressieren.

Ein anderer Unterschied fällt mir gerade nicht ein.

von Stefan T. (stefan90)


Lesenswert?

Ok was ich bisher herausgefunden habe ist, dass ich eine eigene Section 
für meine Variable definieren kann. Nur wie und wo sage ich dem gcc, bei 
welcher Adresse diese Section beginnt?

Ich hoffe dass mir da jemand helfen kann

mfg Stefan

von Andreas K. (a-k)


Lesenswert?

Da GCC sowieso nicht direkt aufs Flash zugreifen kann, sondern 
entsprechende Zugriffsfunktionen explizit verwendet werden müssen, ist 
der Zirkus mit dem Sections bei AVR wenig ergiebig, und man kann 
genausogut direkt mit den Funktionen arbeiten:
 #define read_status()   pgm_read_byte((PGM_P)(FLASHSIZE-1))
 #define write_status(v) pgm_write_byte((PGM_P)(FLASHSIZE-1), v)

Edit: Bei Flash > 64KB müssen die "far" Versionen verwendet werden.

von Andreas K. (a-k)


Lesenswert?

Stefan Tschiggerl wrote:

> Was allgemeines: in der pgmspace.h wird empfohlen, Daten im Flash
> generell in unteren 64k abzulegen. Kann mir jemand sagen warum?

Pointer sind 16 Bits breit. Mehr als 64KB können die folglich nicht 
adressieren. Für Daten jenseits von 64KB Flash müssen also 32 Bit 
Adressen explizit programmiert werden.

von Stefan T. (stefan90)


Lesenswert?

#define read_status()   pgm_read_byte_far((PGM_P)(FLASHSIZE-1))

kann ich damit halt das byte auslesen? wenn das Byte ja im Bereich >64k 
ist, dann geht das mit dem pointer ja nicht mehr oder?

von Andreas K. (a-k)


Lesenswert?

So geht's auch oberhalb von 64KB:
  #define read_status() pgm_read_byte_far(FLASHSIZE-1)

von Wolfgang Horn (Gast)


Lesenswert?

Hi, Stefan,

wie wär's mit der schmutzigen Methode?
Du ergänzt die .hex-Datei des Linkers händisch um einen Intelhex-Record, 
der die speicherstelle wie gewünscht beschreibt.

Etwa so, wie ich die .hex-Dateien zu Firmware und Bootloader zu einer 
gemeinsamen Datei verschmelze.
Studio progrmmiert das schnell.

ciao
Wolfgang Horn

von Stefan T. (stefan90)


Lesenswert?

Wäre sicher möglich, das jedesmal händisch zu machen, aber wenn möglich 
soll das immer bei jedem compilieren automatisch erfolgen.

Um nochmal auf Sections zurückzukommen. Ich verwende WinAVR, kann ich da 
im makefile die Startadresse einer Section definieren? nur wie schaut 
die Zeile hierfür aus?

mfg Stefan

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.