Hallo zusammen,
ich arbeite an einem Projekt mit einem PIC32. Nun sollte ich Information
zur Konfiguration der Software im Flash des PIC ablegen. Leider komme
ich nicht weiter. Wichtig: Das Projekt muss in C programmiert werden
(mir is Assembler zwar lieber, ist aber nicht erlaubt, fragt mich nicht
warum!).
Ich habe bereits funktionen in der P-Lib von Microchip gefunden.
NVMProgram wäre nicht schlecht, allerdings blick ich mit diesem
Memory-Mapping nicht durch. Wo schreibe ich denn meine Daten hin und wo
(wie) lese ich sie wieder aus. Wäre schön wenn ihr mir helfen könntet.
Stephan
So Hallo,
also trotz der wenigen Antworten bin ich bezüglich Memory-Mapping so
weit, dass ich weiß wohin gemappt wird. Fragt mich nicht wie man das
Konfiguriert aber es läuft so. Also zunächst addressiert man immer
Virtual. Der von allen verwendete Speicherbereich zum Speichern
wichtiger Informationen beginnt bei 0x1D000000 (physical) und entspricht
0xBD000000 (virtual).
Das Speichern eines Words habe ich auch hinbekommen. Ich nutze die
Funktion NVMWriteWord aus dem PIC32 Family Datasheet. Problem. Ich kann
nur einmal schreiben. Dann erst wieder nach einem Reset. Ich habe in
verschiedenen Foren, bzw. implizit im Datenblatt gelesen, dass der
Speicher vor dem schreiben gelöscht werden muss. Das ist
nachzuvollziehen, da beim Schreiben ein AND mit den Daten im Speicher
gemacht wird. Das hatte bei meinem Programm folgende Konsequenzen:
zu schreiben (0x34333231)
im Speicher vorher (0x31323334)
im Speicher nachher (0x30323230)
ich habe nun versucht zunächst die Flash Page zu löschen und dann zu
schreiben. Dass hat aber zur Konsequenz dass:
1.) Bei Adresse 0x1D009000 immer ein 0xXXXXXX01 Word steht (XXXXXX sind
die Daten zuvor.
2.) Die Daten nicht gelöscht werden.
3.) Beim Speichern immer noch das beschriebene AND gemacht wird.
Kurioserweise wird nicht Mal ein Fehlerflag gesetzt oder Ähnliches. Auch
die beiden Config Bits die Schuld sein könnten (CP ^= Code Protect und
PWP ^= Program Memory Write Protect) stehen beide auf OFF.
Ich weiss nicht mehr weiter. Ich nutze nur Funktionen aus der PLib oder
dem PIC32 Datenblatt (Copy/Paste) aber es funktioniert nicht.
Sind diese 01 bei 0x1D009000 und in 128 Byte Abständen irgendwelche
Schreibschutz bits?
Weiß jemand Rat, ich habe ihn bitter nötig!
Vielen Dank im voraus
Stephan
hi,
in welchen Schritten adressierst du den Flash? Adress step size ist
nämlich 0x4.
post mal bitte deinen quelltext, bei mir gehts nämlich einwandfrei.
ich habe gemerkt, dass die memory view funktion irgendwie nicht geht,
die daten sind aber auf jeden fall einprogrammiert, da ich diese über
I2C auslesen kann.
gruß
Hallo,
danke Thomas. Die Schrittweite habe ich beachtet.
Zum Problem: Es ist gelöst. Also zunächst, die NVM-Funktionen aus der
PLib funktionieren einwandfrei (sofern man weiß, was für Einschränkungen
sie unterliegen). So kann man z.B. mit NVMWriteWord() ein Word also 32
Bit durchaus schreiben. Jedoch nur ein Mal. Die dem Word zugehörige Row
des Speichers kann dann nicht mehr gelöscht werden. (Erst nach einem
Reset). Damit man die Pages löschen kann müssen immer komplette Rows
geschrieben werden. Verwendet man also stets NVMWriteRow() und
NVMErasePage() und puffert die Daten temporär so ist man auf der
sicheren Seite. Schade das Micro(shit)chip nicht in der Lage ist, das
vernünftig zu dokumentieren.
Das ist meine Funktion die einwandfreie Ergebnisse liefert:
unsigned int NVMWriteWordEx(void* address, unsigned int data)
{
unsigned int buffer[1024];
int i,res;
unsigned int page_address = ((unsigned int)address-((unsigned
int)address%1024));
unsigned int page_offset = ((unsigned int)address%1024)/4;
for(i=0;i<1024;i++)
{
buffer[i] = *((unsigned int*)(page_address+(i*4)));
}
buffer[page_offset] = data;
res = NVMErasePage((void*)page_address);
if(res!=0) return res;
for(i=0;i<8;i++)
{
res = NVMWriteRow((void*)(page_address+(i*128)),
(void*)(buffer+(i*128)));
// Return Result
if(res!=0) return res;
}
}
Die Berechnung von page_address kann man sich theoretisch auch sparen.
Ich habe es zur sicherheit mal implementiert.
Was die Memory-View Funktion von MPLAB angeht: Im wesentlichen
funktioniert das bei mir. (ICD2). Manchmal verabschiedet sich zwar das
Debug-Tool in die ewigen Abgründe des Arbeitsspeichers aber nach
mehrmaligem probieren funktionierts.
OK, ich denke damit ist das Thema abgeschlossen. Falls jemand Probleme
ähnlicher Art hat stehe ich gerne per E-Mail zur Verfügung:
stephan.storm@rebbergnet.de
Tschüss und Ade!
Stephan
Hallo Stephan, habe genau das selbe Problem, welches du zu Beginn
beschrieben hast. Habe dann auch die zuletzt gepostete Funktion kopiert,
und bei mir eingesetzt. Allerdings Funktioniert das beschreiben des
Flashs bei mir nicht wirklich. Für adress habe ich 0xBD000000
eingesetzt.
Eigentlich weiss ich gar nicht wirklich ob es nun im Flash abgespeichert
wird oder nicht, da ich den Befehl zum auslesen nicht kenne.
Darum meine wichtigste Frage: WIE KANN ICH DEN GESPEICHERTEN WERT WIEDER
AUS DEM FLASH-SPEICHER AUSLESEN??
bin schon einige Zeit dran, steh aber voll auf dem schlauch, wäre toll
wenn du mir weiterhelfen könntest.
Danke für die Antwort, aber könntest du mir noch erklären was mir dieser
Code jetzt bringen soll?
Bin (noch) nicht sehr C erfahren und habe deshalb mühe das ohne
erklärung anzuwenden.
Am meisten würde mir ein funktionierender helfen, mit dessen Hilfe ich
Daten vom laufenden Programm aus ins Flash programmieren, und später
wieder auslesen kann.
Vielen dankt nochmals im Vorraus und sorry für die Belästigung, aber
sonst ist im Netz wirklich nicht gerade viel Brauchbares über das Thema
zu finden.
>..könntest du mir noch erklären was mir dieser Code jetzt bringen soll?
Mit dem Pic32 kann man direkt über Zeiger ohne besondere
Funktionenaufruf (wie bei Pic24) das Flash lesen:
1
//Zeiger auf eine 32Bit VIRTUELLE Adresse, bei absoluten Adressen bekommst du einen Fehler
2
UINT32Adress=0x9D000000;
3
//Wert der Adresse lesen
4
UINT32Val=(*((UINT32*)(Adress)));
Beim Flash Schreiben musst du IMMER vorher eine ganze Page(0x1000 Bytes)
löschen, dann mit den NVMWrite-Funktionen schreiben (word oder row)
Ein sehr gutes Beispiel dafür ist der USB-BootLoader von microchip (von
der homepage runterladen), die Funktionen kannst du sicher 1/1
übernehmen.
Vielen Dank erstmal für die tolle Erklärung. Auslesen des Speichers
funktioniert nun einwandfrei! Hätte nicht gedacht das das so einfach
geht...
Welchen USB-Bootloader von Microchip meinst du?
Habe immer noch die Funktion von Stephan implementiert, aber den
Speicherwerwert kann ich noch nicht ändern. Warum, versuche ich nun noch
rauszufinden.
Ok danke. Das file habe ich heruntergeladen und das Projekt "Mass
Storage Bootloader C32" geöffnet. Die Funktion, um ins Flash zu
schreiben kann ich allerdings nicht finden..
Aber funktioniert denn der oben von Stephan gepostete Code nicht? Muss
man bei seinem Code noch die NVMCON Register setzen damit er
funktioniert? Ich versteh einfach nicht, worin mein Fehler liegt...
WOW ja der Beschreibung nach sollte das ja wirklich funktionieren...wäre
ja toll.
Ich habe das jetzt mal heruntergeladen (DEE Emulation 16-bit), darin
wird jedoch der 32MX PIC ja gar nicht aufgeführt... wird der trotzdem
unterstützt, also kann ich die Funktionen einfach so verwenden oder muss
etwas angepasst werden?
ok, ich benutze den PIC32MX440F512H, habe das .c, .h und .s file meinem
Programm hinzugefügt und erhalte beim kompilieren hunderte Fehler wie
unter anderem:
DEE Emulation 16-bit.h:104: error: conflicting types for 'DATA_EE_FLAGS'
oder
DEE Emulation 16-bit.c:100: warning: `space' attribute directive ignored
Keine ahnung aber langsam glaube ich ich bin einfach zu blöd dafür..
Hallo Leute,
und schon wieder ist ein Arbeitstag ins Land gezogen, ohne dass wirklich
ein Fortschritt bei meinem Projekt passiert ist.
Ich habe heute Alles. was mit dem Aeschreiben meines Flashs zu tun hat,
nochmals aus dem Programm gelöscht und neu imolementiert. Alles schön
nach Datenblatt wie ich meine...aber es funktioniert einfach nicht.
Ich bitte deshalb darum, dass Jemand der einen funktionierenden C-Code
besitzt diesen doch bitte hier posten könnte (mit Funktionsaufruf und
allem was dazu gehört / was man sonst noch falsch machen könnte). Dafür
wäre ich euch wirklich sehr dankbar!
Ansonsten bleibt mir nur noch die möglichkeit, ein externes EEPROM
nachträglich auf den extern gefertigten Print zu fädeln -.-
Vielen Dank im Voraus
Nicola
Al schrieb:> Na, hättest du das Beispiel von USB-Bootloader für PIC32 genommen,> hättest du jetzt keine Probleme mehr!
Hab ich mir ja angeschaut aber in der .zip datei die ich heruntergeladen
habe, hat es sehr viele files. Köntest du bitte den codeteil nennen, den
du meins oder zumindest den namen des files damit ich weiss, wo ich
suchen muss? Sollte das problem wirklich schnellstmöglich lösen...oder
besser gesagt: ich sollte es schon gelöst haben :-S
Gruss
hier ist ein Muster:
- Prüfe vor dem Schreiben ob die Page schon gelöscht ist oder nicht
- Schreibe im Flash Wortweise (du kannst es dann anpassen)
Gruß
Vielen dank für die Mühe A1, jetzt habe ich doch noch die Hoffnung, es
heute noch hin zu kriegen.
Hab den Code jetzt bei mir eingebunden, allerdings Funktionieren die
Befehle "IntHex32Packet.dataLen" und "IntHex32Packet.baseAddress" nicht.
Ich kenne die Befehle erlich gesagt auch nicht, kannst du mir sagen wie
ich den Fehler beheben kann?
gruss
So, nochmal zur EEPROM Emumation Library. Ich benutze das, um beim
Microchip TCPIP Stack die Netzwerkkonfiguration in einem nichtflüchtigen
Speicher abzulegen. Bei mir sieht das so aus:
Konfiguration wird beim Booten gelesen:
ojeeeeeeeeeee Nicola!
du kannst wohl nicht programmiern!!
Das wird natürlich nicht auf Anhieb funktionieren, es war nur ein Teil
von meinem Bootloader.
Für das Prüfen/Löschen der Pages und Flash-Schrieben reichts es aber.
Du musst es jetzt zu deiner Applikation anpassen:
("IntHex32Packet ist eine Sturktur wo ich die Daten zum schreiben
speichere")
du musst dann deine Daten holen und in WriteToFlash() ersetzen.
was ist überhaupt deine Aufgabe?
Was willst im Flash schrieben? große Menge Daten? nur eine ID oder ein
Int??
Es geht darum, verschiedene Prüfprogramme abzuspeichern. Würde mir aber
reichen, wenn ich z.B. 0xFFFFFFFF abspeichern könnte, dann wüsste ich
wieder, wie ich weitermachen muss.
Und nein, ich kann wirklich noch nicht so gut programmieren, lerne aber
laufend dazu...hoffe ich
Gruss
dann definiere dir einen extra Speicherbereich dafür, feste Flash
Adressen, wichtig ist:
- Da du nur ganze Pages löschen kannst, muss das ganze in pages
aufgeteilt sein
1- Der Compiler darf in diesem Bereich nichts schreiben, also hier wird
es noch komplezierter: Der Linker musst anpassen werden
2- Linker anpassen: im Linker script:
1
kseg0_program_mem(rx):ORIGIN=0x9D000000,LENGTH=0x40000/* Main */
2
// ändern auf zum Beispiel
3
kseg0_program_mem(rx):ORIGIN=0x9D000000,LENGTH=0x40000-0x1000/* Main */
jetzt hast du die letzte page nur für deine Daten.
Was sind verschiedene Prüfprogramme?, werden dann gestartet?
Prüfprogramme ist ein wenig übertrieben...es handelt sich um daten wie
Artikelnummer, Zielwert, Toleranz usw. also um einen Struct eigentlich.
Naja ich schaus mir am Wochenende nochmals an...komm nicht ganz draus
was in dem Beispielprogramm von heute morgen genau passiert..hatte heute
aber auch keine zeit, daran zu arbeiten...
Wenn noch jemand einen Funktionierenden Code für mich hat, bei dem am
bessten nur Adresse und Daten eingegeben werden müssen, bitte Posten!
Allen noch schönes Wo.Ende!