www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik PIC32 Daten im Flash ablegen


Autor: Stephan Storm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Stephan Storm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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ß

Autor: Stephan Storm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Nicola (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Al (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
UINT32 Adress = 0x9D000000; // virtuelle adresse!!!!!!!!!!!!!!

UINT32 Val = (*(UINT32*)(Adress));

Autor: Nicola (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Nicola (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Al (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>..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:
//Zeiger auf eine 32Bit VIRTUELLE Adresse, bei absoluten Adressen bekommst du einen Fehler
UINT32 Adress = 0x9D000000; 
//Wert der Adresse lesen
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.

Autor: Nicola (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Al (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?IdcServic...

Autor: Nicola (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: heinzhorst (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum so kompliziert? Ich mache das auf dem PIC32 mit der Data EEPROM 
Emulation Library von Microchip:

http://www.microchip.com/stellent/idcplg?IdcServic...

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.

Autor: Nicola (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: heinzhorst (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein, da muss nichts angepasst werden. Das macht der Präpozessor beim 
Compillieren von alleine. Ich benutze das auf einem PIC32MX795.

Autor: Nicola (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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..

Autor: Nicola (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Al (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na, hättest du das Beispiel von USB-Bootloader für PIC32 genommen, 
hättest du jetzt keine Probleme mehr!

Autor: Nicola (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Al (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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ß

Autor: Nicola (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: heinzhorst (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:

#include "dee_emulation_pic32.h"

// EEPROM mapping

#define EEPADR_APPCONF  0

// initialisierung
DataEEInit();

// Konfiguration aus EEPROM in RAM kopieren
DataEEReadArray(&AppConfig, EEPADR_APPCONF, sizeof(AppConfig));


oder zum Wegspeichern:

// Konfiguration aus RAM in EEPROM kopieren
DataEEWriteArray(&AppConfig, EEPADR_APPCONF, sizeof(AppConfig));

PackEE();


Autor: Günther (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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??

Autor: Nicola (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Günther (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
kseg0_program_mem    (rx)  : ORIGIN = 0x9D000000, LENGTH = 0x40000 /* Main */ 
// ändern auf zum Beispiel
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?

Autor: Nicola (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.