Hallo zusammen,
ich verwende den PIC24. Nun möchte ich eine konstante Variable an einen
bestimmten Speicherplatz im Flash setzen. Dies mache ich mit:
const unsigned char Variable __attribute__((address(0x800))) = 123;
ich denke das funktioniert sowei. Zumindest zeigt er mir im Mapping eine
Variable an der Adresse 0x800 an.
Nun möchte ich diesen Wert im Programm in eine normale unsigned char
Variable einlesen. Also etwa so:
unsigned char* const xxx = 0x800;
unsigned char yyy = (unsigned char)*xxx;
Leider hat die Variable yyy hinterher nicht den Wert 123. Was mache ich
falsch?
Das Ganze ist für einen Bootloader. Im Bootloader möchte ich die
Bootloaderversion an eine bestimmte Adresse speichern, sodass ich im
Hauptprogramm die Version auslesen kann.
Vielen Dank!
Markus
Markus Wi, schrieb:> const unsigned char Variable __attribute__((address(0x800))) = 123;>> ich denke das funktioniert sowei. Zumindest zeigt er mir im Mapping eine> Variable an der Adresse 0x800 an.
Ich denke, das solltest du erst mal verifizieren.
Ich würde das nicht mit einem Mapping kontrollieren, sondern ganz
konkret den Bootloader (aus dem ja dieses Stück Code stammt) in den
Flash brennen und dann mit einem Speicher-Dump Programm im Speicher
nachsehen, ob an der bewussten Stelle im Flash tatsächlich 123 zu finden
ist.
Kontrolle auf tiefster Ebene ist immer gut.
Danke für die Antwort!
Ich habe es jetzt so probiert:
Bootloader:
const unsigned char Variable __attribute__((address(0x800))) = 123;
Anwendungsprogramm:
const unsigned char xxx __attribute__((address(0x800)));
unsigned char yyy = (unsigned char)xxx;
if (yyy == 123) while(1);
Leider immer noch das gleiche: yyy = 0.
Karl Heinz schrieb:> Ich denke, das solltest du erst mal verifizieren.> Ich würde das nicht mit einem Mapping kontrollieren, sondern ganz> konkret den Bootloader (aus dem ja dieses Stück Code stammt) in den> Flash brennen und dann mit einem Speicher-Dump Programm im Speicher> nachsehen, ob an der bewussten Stelle im Flash tatsächlich 123 zu finden> ist.
Das wollte ich verifizieren. Allerdings habe ich keine Ahnung wie das
geht. Deshalb "nun" über daas Mapping. Ich habe MPLABX und ein ICD3
hier. Kann man im MPLABX irgendwie den Speicher wieder auslesen? Oder
kann man es über das Hexfile machen? Allerdings weis ich auch hier nicht
wie ich die Adresse 0x800 im Hex-File finde.
Markus Wi, schrieb:> const unsigned char Variable __attribute__((address(0x800))) = 123;> Nun möchte ich diesen Wert im Programm in eine normale unsigned char> Variable einlesen. Also etwa so:>> unsigned char* const xxx = 0x800;> unsigned char yyy = (unsigned char)*xxx;
Entweder ich bin noch nicht ganz wach oder das eine passt u.U. nicht zum
anderen...
Zeiger auf eine Konstante:
const unsigned char * ptr2const;
Konstanter Zeiger:
unsigned char * const constPtr;
Arc Net schrieb:> Entweder ich bin noch nicht ganz wach oder das eine passt u.U. nicht zum> anderen...> Zeiger auf eine Konstante:> const unsigned char * ptr2const;> Konstanter Zeiger:> unsigned char * const constPtr;
Daran habe ich auch schon gedacht. Habe bereits beide Varianten
ausprobiert.
Der PIC24 hat eine Harvard-Arhcitektur, d.h. Du hast unterschiedliche
Adressräume für RAM und Flash.
Der PIC24 hat zwei Möglichkeiten, um aus dem Flash zu lesen:
1. Durch Einlenden eines bestimmten Flash-Fensters im RAM-Adressraum.
Dieses Fenster wird i.a.R. automatisch vom Compiler verwaltet.
2. Über die "TBLRD"-Befehle.
Schau mal in Dein Compiler-Handbuch, da gibt es Intrinsic-Befehle zum
Lesen aus dem Flash (hab leider gerade keine Doku da).
Ich hab in meinem Code da folgendes drinn:
Also, ich habe herausgefunden, wie man mit MPLABX den PIC ausliest und
den Speicher anzeigt.
const unsigned char Variable __attribute__((address(0x800))) = 123;
funktioniert. An der Speicherstelle 0x800 im Flash finde ich den Wert
0x7B was ja dem dezimalen Wert 123 entspricht.
Also liegt das Problem am Auslesen des Wertes aus dem Flash.
Ja, lies dich mal in das Thema "program space visibility (PSV)" ein,
dann wirst du erkennen wo das Problem liegt :)
Der PIC kann nur einen Teil vom RAM-Adressraum ins FLASH mappen, darum
sollte man das tunlichst dem Compiler überlassen wo er seine Konstanten
hinlegt!
Ich mach das bei meinen Bootloader zwar ähnlich wie du was das ablegen
der Konstanten betrifft, auslesen tu ichs aber wie schon über mir
beschrieben über die "TBLRD"-Befehle.
Super!!! Vielen, vielen Dank!!! So funktioniert es jetzt!!!
Folgenden Code habe ich jetzt verwendet:
unsigned long FlashReadSingleWord(unsigned long addr_u32)
{
asm(" push TBLPAG ");
asm(" mov W1,TBLPAG ");
asm(" tblrdh [W0],W1 ");
asm(" tblrdl [W0],W0 ");
asm(" pop TBLPAG ");
}
unsigned long yyy = FlashReadSingleWord(0x800);
unsigned char xxx = (unsigned char)yyy;
Ich werde mich jetzt noch einlesen, was da genau passiert, aber ich bin
schon mal ein ganzes Stück weiter!
Beim Compilieren bekomme ich jetzt noch folgende Fehlermeldung:
warning: control reaches end of non-void function
klar, der Compiler vermisst das return in der Funktion. Kann man das
irgendwie lokal ausschalten? Das stört mich ein wenig.
Markus Wi, schrieb:> klar, der Compiler vermisst das return in der Funktion. Kann man das> irgendwie lokal ausschalten? Das stört mich ein wenig.
Also zumindest beim C30 (jetzt X16) hab ich das auch schon gesucht und
nicht herausgefunden.
Aber schau dir mal die Intrinsic-Funktionen an, vielleicht gibt's da was
besseres...
Markus Wi, schrieb:> lokal ausschalten? Das stört mich ein wenig
Das return muß rein in die Funktion.
Dazu definierst Du eine Variable, ungeähr so, hab jetzt keine lust das
in MPLab zu testen:
unsigned int FlashReadSingleWord(unsigned long addr_u32)
{
unsigned int flash_word
asm(" push TBLPAG ");
asm(" mov W1,TBLPAG ");
asm(" tblrdh [W0],W1 ");
asm(" tblrdl [W0],W0 ");
asm(" mov W0, flash_word ");
asm(" pop TBLPAG ");
return flash_word
}
Kann man auch auf long erweitern mit union