Forum: Mikrocontroller und Digitale Elektronik MSP430 (F2013)Wie Zur Laufzeit Daten im Flash ablegen...


von Kwi (Gast)


Lesenswert?

Hallo,

hab mir das Entwicklungskit im USB Stickformat besorgt (EZ430).

Komme damit sehr gut zurecht, Watchdog/Timer geht alles Problemlos.
Da ich relativ neu auf dem MSP Sektor bin, habe ich eine Frage:

-
Wie kann ich z.B ein Byte, zur Programmlaufzeit auf dem uC, in das Flash 
zu Programmieren?
-

Dabei wuerde mir ein Byte erstmal genuegen, nur um die Logik zu 
verstehen, wie dies im MSP realisiert wird.

kann ich die Variablen (mit einem Schluesselwort), schon zur 
Programmierzeit eine Flashspeicherstelle zuweisen?

Darum geht es nur eine feste zur Programmierzeit bekannte Anzahl von 
"Bytes" zu speichern in etwa so

int iWillInsFlash;
(Mach was mit iWillInsFlash...)
StoreFlash(iWillInsFlash[,iPosFlashByte])

...

und auch anderstrum (Nach Stromweg)

int iWillWasAusFlashHaben;
iWillWasAusFlashHaben = Retr(iPosFlashByte);

(Wieder da freu...)




von Kwi (Gast)


Lesenswert?

Ok habs gefunden, in den Codebeispielen...

Nur noch eine Frage...

Wie stelle ich sicher das das FlashSegment nicht schon "belegt" ist 
durch mein Programm?

von Kwi (Gast)


Lesenswert?

Auch wenn ich mit mir selbst reden, vielleicht hilfts jemand...

fet140_flashwrite_01.c

und laut Datenblatt...

Information memory Size
Flash
256 Byte
010FFh − 01000h

Is ja sehr einfach, gefaellt mir immer mehr ;)

von Tilo S. (thesurfer)


Lesenswert?

Generell ist der nicht beschriebene Bereich mit 0xFF belegt.

Pass aber auf den letzten Bereich des Flashspeicher auf, denn dort 
stehen die Kalibrierungsdaten fuer 1,8,12,16 MHz Taktung.

Naemlich dieser bereich :

010FFh
010FEh
010FDh
010FCh
010FBh
010FAh
010F9h
010F8h

den hab ich auch schon mal geloescht, da lief der gute dann mit 19 MHz 
egal was ich fuer Register gesetzt hatte :( , naja beim zweiten F2013 
den Bereich wieder ausgelesen und auf den zerstoerten wieder 
raufgeschrieben und das Problem war geloest.

von Kwi (Gast)


Lesenswert?

Kann ich auch nur ein Byte schreiben, oder muss ich ein Seg mit 128 Byte 
erst löschen?

  FCTL3 = FWKEY;                            // Clear Lock bit

  FCTL1 = FWKEY + WRT;                      // Set WRT bit for write 
operation



    *Flash_ptr = DerWert;                   // Write value to flash


  FCTL1 = FWKEY;                            // Clear WRT bit
  FCTL3 = FWKEY + LOCK;                     // Reset LOCK bit
}

von Kwi (Gast)


Lesenswert?


pragma memory=dataseg(INFO)
static word w1;
static byte b1;
static byte b2;


Dann die obrigen sachen fuettern...

Kann ich nun fuer jedes Byte/Word flashme aufrufen ohne das die anderen 
drunter leiden , geloescht werden?


void flashme(word* address, word (oder byte) data)
{
// Interupts vielleicht Disable?

  FCTL3 = FWKEY;        // Unlock the flash.
  FCTL1 = FWKEY | WRT;  // Enable flash write.
  *address = data;      // Write the data to the flash.
  FCTL1 = FWKEY;        // Disable flash write.
  FCTL3 = FWKEY | LOCK; // Lock the flash.

}

von Tilo S. (thesurfer)


Lesenswert?

jo kannst du. wobei ein kollege von mir jeweils eine Funktion fuer byte, 
word und dword geschrieben hat. Mit deiner verglichen sieht sie aehnlich 
aus nur das er noch wartet bis er schreiben darf.
1
void flash_write_word(unsigned int *address, unsigned int val)
2
{
3
  do {
4
  _NOP();
5
  } while(FCTL3 & BUSY);   // warten, solang BUSY gesetzt ist
6
  FCTL3 = FWKEY;        // Sperre aufheben (UNLOCK)
7
  FCTL1 = FWKEY + WRT;  // ein Word schreiben
8
  *address = val;    // Wert der Speicherzelle zuweisen  
9
}

von Kwi (Gast)


Lesenswert?

Wunderbar, lauft bei mir ;)

Kurze Frage noch: Koennt ja auch im Flash wo das Programm eingebrannt 
wird, während der Laufzeit "Befehle","Daten" umflashen?

Oder ist diese Speicherstellen (wo das Programm ist) anderst 
organisiert?
Koennt ja dann einen ungenutzten FlashProgrammspeicher als Datenspeicher 
missbrauchen? Anstatt ~256Bytes sinds ja bei dem 2013er 4KB.

Hab in einem Ti-Dokument gelesen, das man da erst das Programm ins Ram 
reinschieben muss, weil sonst die CPU keinen Zugriff, beim Flashen, aufs 
Programm hat.

P.S. Fuehl mich gerade an meine C64 Asm Zeit zurueckerinnert ;) Man scho 
14Jahre her ;)

Naja einfacher waers ja einfach nen I2C EEprom anzuschliessen, die gibts 
ja inner annehmbaren groesse...

von Andi (Gast)


Lesenswert?

Hallo!

Nachdem ich schon viel versucht habe und eigentlich auch schon alles 
gelesen habe was die Suche gefunden hat, muss ich jetzt doch mal fragen.

Ich möchte Daten / Variablen im Flash speichern, damit ich diese nach 
Strom ausfall wieder laden kann. Diese können sich während der laufzeit 
ändern bzw. werden erst während der laufzeit "eingelernt", d.h. es kann 
sein das ich diese auch aktualisieren muss.

Dazu möchte ich mir mittels einer #pragma Anweisung Speicherplatz im 
Flash "reservieren", nur leider krieg ich das nicht hin.

Am besten wäre ein Array mit z.B. 8 Feldern und eine INT Variable im 
Flash oder evtl sogar eine kleine structur, mit einer INT Variable und 
einem Array mit 8 Feldern

Mit dieser Anweisung von oben:
#pragma memory=dataseg(INFO)   //Sollte INFO nicht im Flash sein???
char array[8]
#pragma memory=default

wird die Variable im Ram bei Adresse 200 abgelegt.

Wie muss ich das anstellen damit ich das ins Flash bekomme?

Daten in absolute Adressen des Flashs zu kopieren ist kein Problem, das 
funktioniert, nur eben nicht wenn mich mir Speicher mittels einer 
#pragma Anweisung reservieren will.

Ich verwende die neueste IAR Workbench und arbeite mit dem MSP430F149 
und der JTAG Tiny von Olimex sowie dem neuem "USB-Stick" mit dem F2013.

Vielen Dank schon mal!

Gruß Andi

von Christian R. (supachris)


Lesenswert?

Das geht so nicht. Zum Beschreiben des Flashes muss eine bestimmte 
Prozedur eingehalten werden. Die kennt der Compiler nicht. Entweder du 
kennzeichnest die Variablen als const, dann landen sie zwar im Flash, 
aber du kannst sie nur lesen. Oder de beschreibst den Flash wie in den 
C-Demos von TI angegeben.
Der Flash kann nur durch den Debugger beim Download des Programm, durch 
den Bootloader oder durch die Flash-Routine zur Laufzeit geschrieben 
werden.
Desweiteren muss das entsprechende Flash-Segment vorher gelöscht werden, 
aber das steht ja alles in den C-Demos und im User Guide.

von Andi (Gast)


Lesenswert?

Hi!

Hmm... das das beschreiben während der Laufzeit nur über die Routine 
möglich ist, war mir schon bewusst, dachte nur das ich über #pragma 
memory bzw. #pragma location ein "segment" bzw. speicher im Flash 
reservieren kann das ich dann über die Routine beschreiben kann.

Die Adresse der Variable hätte ich dann mit & übergeben und dann mittels 
Zeiger gemäß C-Demos ins Flash geschrieben.

Gruß Andi

von Andi (Gast)


Lesenswert?

Hallo nochmal.

Also mit #pragma location hab ichs jetzt hinbekommen:

#pragma location=0x1000
    __no_init UINT8 anzahl;

#pragma location=0x1080
    __no_init UINT8 variable[8];

So kann ich jetzt mit &anzahl die Adresse holen und mit der Routine 
mittels Zeiger ins Flash schreiben.

Allerdings muss ich dies jetzt zweimal machen für 2 Variablen.
Falls mir jemand sagen kann wie das evtl elleganter geht, wäre ich sehr 
dankbar.

Gruß Andi

von Stefan (Gast)


Lesenswert?

Den Zeiger inkrementieren:
1
UINT8 * p_anzahl;
2
UINT    anzahl;
3
4
p_anzahl = &anzahl;
5
6
//  mit p_anzahl daten ins flash schreiben
7
8
p_anzahl++;
9
10
// p_anzahl zeigt auf den nächsten Flash-Speicherbereich

von Christian R. (supachris)


Lesenswert?

Achso...das ist dann also ein Linker-Problem. Na gut, da konnt ich dir 
nicht helfen, arbeite mit mspgcc, da hab ich meine Linker-Scripte 
angepasst, um solche Sachen zu realisieren.

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.