Forum: Mikrocontroller und Digitale Elektronik MSP430F155 Probleme beim Speichern im Flash


von Lars D. (eitum)


Lesenswert?

1
void fnWriteFlash (unsigned int uiType, float fValue)
2
{
3
  float  *Flash_ptr;
4
5
  _DINT();
6
  Flash_ptr   =   (float *) uiType;
7
  FCTL1    =   FWKEY + ERASE;
8
  while(FCTL3 & BUSY);                      // Check Flash BUSY bit
9
  FCTL3    =  FWKEY;
10
  FCTL1    =  FWKEY + WRT;
11
  *Flash_ptr  =  fValue;
12
13
  FCTL1    =  FWKEY;
14
  FCTL3    =  FWKEY + LOCK;
15
16
    while(!(FCTL3 & WAIT));                 // WAIT until Flash is ready
17
    _EINT();
18
  return;
19
}

Das is meine Routine zum Speichern von Maximalwerten. Beim 
Initzialisieren des Flashs werden alle Daten korrekt geschrieben und ich 
kann sie auch ohne Probleme korrekt auslesen.
Wenn ich nun einen Wert Aktualisieren möchte weil halt neuer Maximalwert 
gemessen wurde, Wird ein falscher Wert geschrieben.

z.B.
*Flash_ptr zeigt auf 0x1014 nach init hat er den Wert 20.0
fValue soll mit 99.0 beschrieben werden.
nach der Zeile *Flash_ptr = fValue; steht an der Stelle 4.0

Ich kann leider nicht mittels dummy write das Segment löschen, da sonst 
alle Messewerte verschwunden sind.

Hat einer Vorschläge?

Danke

von Stefan (Gast)


Lesenswert?

Das ist das Wesen eines Flash Speichers, dass man ihn erst segmentweise 
löschen muss, bevor man was neues reinschreiben kann!
Sichere den aktuellen Inhalt des Segments im RAM, lösche das Segment, 
Update der Daten im RAM und neu ins Flash schreiben!

von Lars D. (eitum)


Lesenswert?

Gibt es da irgendwelchen Beispielcode, oder wie bekomm ich das in den 
RAM? Byteweise in ein Array verlagern und dann wieder zurück oder wie?

von Christian R. (supachris)


Lesenswert?

Genau so. Halt vom Flash in in Array lesen, was so groß ist, wie das 
Segment und da die Werte aktualisieren, Segment löschen und wieder 
zurück schreiben.
Wäre da ein externer EEPROM nicht besser? Wie oft passiert das denn?

von Lars D. (eitum)


Lesenswert?

Ist ein Temperatursensor der sich seine Maximalwerte und einige 
Kalibrierungswerte merken soll. Die Maximalwerte aktualisieren sich am 
Anfang noch recht oft später dann kaum noch .. kalibrierung erfolgt auch 
eher selten.

Über ein Beispiel würde ich mich trotzdem freuen, da ich mit Pointer 
immer so meine Probleme habe. Vor allem weil der Datentyp nicht char 
sondern float ist, bin ich mir nicht sicher betreff Mapping.

von Jörg S. (joerg-s)


Lesenswert?

Beispiele gibt's bei TI (fet140_flashwrite_01.c):
1
void write_SegA (char value)
2
{
3
  char *Flash_ptr;                          // Flash pointer
4
  unsigned int i;
5
6
  Flash_ptr = (char *) 0x1080;              // Initialize Flash pointer
7
  FCTL1 = FWKEY + ERASE;                    // Set Erase bit
8
  FCTL3 = FWKEY;                            // Clear Lock bit
9
  *Flash_ptr = 0;                           // Dummy write to erase Flash segment
10
.
11
.
12
.

von Jörg S. (joerg-s)


Lesenswert?

Du kannst das Löschen übrigens vermeiden wenn du weisst das du nur Bits 
auf 0 setzen willst. Von 1 auf 0 geht bei Flash immer, nur um von 0 auf 
1 zu kommen muss ein ganzes Segement gelöscht werden.

von Lars D. (eitum)


Lesenswert?

Die Beispiele von TI hatte ich. Ich hatte nur ein paar Probleme weil 
float ja 2 Byte is.

Folgende Lösung hab ihc jetzt. Sie funktioniert. Falls mal jemand das 
Gleiche Problem hat.
1
float fnReadFlash (unsigned int uiType)
2
{
3
  float   fReadValue  =  0;
4
  float  *Flash_ptr;
5
6
  Flash_ptr  =  (float *)(0x1000 + (0x04 *uiType));
7
8
  fReadValue  =  *Flash_ptr;
9
10
  return (fReadValue);
11
}
12
13
void fnWriteFlash (unsigned int uiType, float fValue)
14
{
15
  float      *Flash_ptr;
16
  float       Backup[64];
17
  unsigned int   i       =   0;
18
19
  Flash_ptr  =  (float *) 0x1000;
20
21
    for (i=0; i<64; i++)
22
    {
23
      Backup[i] =  *Flash_ptr++;
24
    }
25
    Backup[uiType]   =  fValue;
26
27
  Flash_ptr   =   (float *) 0x1000;
28
  FCTL1    =   FWKEY + ERASE;
29
  FCTL3    =  FWKEY;
30
  *Flash_ptr  =  0;
31
  FCTL1    =  FWKEY + WRT;
32
33
    for (i=0; i<128; i++)
34
      {
35
        *Flash_ptr++  =  Backup[i];
36
      }
37
  FCTL1    =  FWKEY;
38
  FCTL3    =  FWKEY + LOCK;
39
40
41
  return;
42
}

von S. Z. (szimmi)


Lesenswert?

Warum zaehlst Du bei der zweiten Schleife bis 127?

von Lars D. (eitum)


Lesenswert?

ups vergessen zu ändern.. hatte erst überall 128 aber da float ja 2 byte 
is gabs dann immer nen absturz wegen pointer ins nirvana.

Danke für den Hinweis.

von Christian R. (supachris)


Lesenswert?

Float sind 4 Byte und nicht 2.

von Em G. (exe87)


Lesenswert?

Guten Morgen zusammen,
auch wenn dieser Thread schon ein wenig älter ist,
aber kann mir vielleicht jemand etwas erklären!?
Ich verstehe diese Zeile nicht so ganz, bzw kann mir nicht genau 
erklären, was sie bewirkt.

Lars D. schrieb:
> Flash_ptr  =  (float *)(0x1000 + (0x04 *uiType));

von Tobias K. (kurzschluss81)


Lesenswert?

Das ist eine Zeiger Operation  (zuordnung)
1
(float*) // Typekonvertierung in einen Zeiger vom Typ Float
2
(0x1000 + (0x04 * uiType)) // die 0x1000 ist die Gundadresse 
3
(0x04 * uiType) // 0x04 wird ein Multiplikator sein (ich glaube Floate ist 4Byte groß) und in uiType könnte die Menge der Varaiblen enthalten ein.
Aber mehr kann ich hier nicht rauslesen dazu bräuchte ich mehr Code

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
Noch kein Account? Hier anmelden.