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
Was passiert, wenn du die Schreibweise mit der Adressvergabe in deinem Anwendungsprogram duplizierst?
1 | unsigned char xxx __attribute__((address(0x800))); |
2 | unsigned char yyy = yyy; |
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:
1 | uint32_t FlashReadSingleWord(uint32_t addr_u32) |
2 | {
|
3 | asm(" push TBLPAG ");
|
4 | asm(" mov W1,TBLPAG ");
|
5 | asm(" tblrdh [W0],W1 ");
|
6 | asm(" tblrdl [W0],W0 ");
|
7 | asm(" pop TBLPAG ");
|
8 | } |
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.