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.
UINT32 Adress = 0x9D000000; // virtuelle adresse!!!!!!!!!!!!!! UINT32 Val = (*(UINT32*)(Adress));
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 | UINT32 Adress = 0x9D000000; |
3 | //Wert der Adresse lesen
|
4 | UINT32 Val = (*((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.
auf der Microchip Seite / Pic32 oder USB Teil findest du viele Beispiele, auch von dem Bootloader für die Pic32 Reihe. USB Framework for PIC18, PIC24 & PIC32: http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2680&dDocName=en537044
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...
Warum so kompliziert? Ich mache das auf dem PIC32 mit der Data EEPROM Emulation Library von Microchip: http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2680&dDocName=en538000 Ist eine fertige Rundum-Glücklich-Lösung und hat die selbe Syntax, wie die Funktionen, mit denen du ein einen "echten" EEPROM im PIC beschreibst.
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?
Nein, da muss nichts angepasst werden. Das macht der Präpozessor beim Compillieren von alleine. Ich benutze das auf einem PIC32MX795.
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
Na, hättest du das Beispiel von USB-Bootloader für PIC32 genommen, hättest du jetzt keine Probleme mehr!
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:
1 | #include "dee_emulation_pic32.h" |
2 | |
3 | // EEPROM mapping
|
4 | |
5 | #define EEPADR_APPCONF 0
|
6 | |
7 | // initialisierung
|
8 | DataEEInit(); |
9 | |
10 | // Konfiguration aus EEPROM in RAM kopieren
|
11 | DataEEReadArray(&AppConfig, EEPADR_APPCONF, sizeof(AppConfig)); |
oder zum Wegspeichern:
1 | // Konfiguration aus RAM in EEPROM kopieren
|
2 | DataEEWriteArray(&AppConfig, EEPADR_APPCONF, sizeof(AppConfig)); |
3 | |
4 | PackEE(); |
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!
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.