Forum: Mikrocontroller und Digitale Elektronik MSP Flash Infomemory benützen


von David K. (kresley81)


Lesenswert?

Hallo zusammen

Ich versuche in die Programmierung des Flash-Speichers einzusteigen. Es 
ist mein erster Versuch. Ich habe bereits ein Beispielprogramm von TI 
ausprobiert, aber es hat lieder nicht funktioniert. Ich benütze die 
Programmierumgebung AQ340. Das Flash beschreiben funktioniert. Doch wenn 
ich ein Segment lösche, hängt sich das Programm auf.
Muss man die AQ430 Programmierumgebung speziell konfigurieren, wenn man 
vor hat, den FLASH zu benützen, damit sie den Info-Bereich reserviert?

Mein Programm:

void main (void)
{    int dummy;
     int i;
     WDTCTL = WDTPW + WDTHOLD;    // Stop watchdog timer
    initMSP();                      // Initialize the MSP 
Microcontroller

    _DINT();
    flash_erase((unsigned char*)0x1000);        // Segemnt löschen
    flash_write_byte((unsigned char*)0x1000, 0);   // Wert schreiben
    _EINT();

    for(i=0; i<128; i++)          // Flash auslesen
    {
  flashcopyB[i] = *flashpointer++;
    }
    flashpointer = (unsigned char*)0x1000;

    while(1)                        // Stay here forever
    {
         dummy++;
         dummy--;
    }
}



void flash_write_byte(unsigned char *address, unsigned char val)
{
  FCTL3 = FWKEY;              // Sperre aufheben (LOCK)
  FCTL1 = FWKEY + WRT;        // Writebit setzen

  while(FCTL3 & BUSY)  // Warten bis Freigebe
  {
     _NOP();
  }

  *address = val;         // Wert der Speicherzelle zuweisen

  while(FCTL3 & BUSY)  // Warten bis Freigebe
  {
      _NOP();
  }

 FCTL1 = FWKEY;        // Writebbit löschen
 FCTL3 = FWKEY + LOCK;      // Lock
}


void flash_erase(unsigned char *address)
{

  while(FCTL3 & BUSY)  //Warten bis Freigebe
  {
  _NOP();
  }

  FCTL3 = FWKEY;                     // Clear Lock bit
  FCTL1 = FWKEY + ERASE;             // Set Erase bit

  *address = 0;                      // Dummy write to erase Flash 
segment

  while(FCTL3 & BUSY) //Warten bis Freigebe
  {
      _NOP();
  }

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

von David K. (kresley81)


Lesenswert?

Vergessen: Das ganze spielt sich auf dem MSP430F449 ab.

Danke im voraus für jede Antwort

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Der Programmteil, in dem das Flash programmiert wird, darf nicht aus dem 
Flash heraus ausgefürt werden, da beim Programmieren des Flashs 
Lesezugriffe auf selbiges nicht möglich, zur Ausführung des Programmes 
aber nötig sind.

Die betreffenden Programmteile müssen daher vorher ins RAM kopiert und 
aus dem RAM heraus aufgerufen werden.

Dazu müsste es eigentlich auch 'ne Application Note von TI geben.

Das hier

http://focus.ti.com/mcu/docs/mcusupporttechdocsc.tsp?sectionId=96&tabId=1502&abstractName=slaa341

beschreibt einen "Flash Monitor", so eine Art Bootlader, mit dem der 
MSP430 über die serielle Schnittstelle programmiert werden kann. Dazu 
müssen dieselben Techniken wie beim Programmieren des Infomemory 
angewandt werden.

Zitat aus dem "MSP430x4xx Family User's Guide (Rev. F)*", Seite 6-4 
(310)

  Reading or writing to flash memory while it is being programmed
  or erased is prohibited. If CPU execution is required during
  the write or erase, the code to be executed must be in RAM.

Zwar ist auf den nachfolgenden Seiten desselben Dokumentes auch 
beschrieben, wie ein Programmieren des Flashs aus dem Flash heraus 
durchgeführt werden kann (Seite 6-10 etc.), das aber ist nicht mit den 
von Dir verwendeten Warteschleifen möglich, da der Prozessor während des 
eigentlichen Schreibvorganges "hängt" und keinen Code aus dem Flash 
ausführen kann.



*) http://www.ti.com/litv/pdf/slau056f

von Christian R. (supachris)


Lesenswert?

Stimmt nicht ganz. Man darf sehr wohl auf dem Flash arbeiten, wenn man 
das Programm aus dem Flash ausführt. Allerdings kann man nicht das 
Segment, in dem gerade Code ausgeführt wird, löschen oder beschreiben. 
Den InfoMem kann man jedoch während der Laufzeit jederzeit 
beschreiben/löschen.
Ich hab das selbst gemacht, um z.B. bei einem programmierbaren Netzteil 
bevorzugte Wertekombinationen abzulegen. Mit dem Beispiel von TI in den 
C-Demos gings problemlos.

@David: Ich glaub, du hast nur vergessen, den richtigen Takt für den 
Flash-Controller auszuwählen, du musst noch

FCTL2 = FWKEY + FSSEL0 + FN0;             // MCLK/2 for Flash Timing 
Generator

einstellen. Oder ein anderes FSSELx je nachdem.

Wichtig zu wissen, ist noch, dass die CPU steht, wenn man aus dem Flash 
heraus den Flash beschreibt. Aber dürfte ja in deiner Anwendung nicht 
von Belang sein.

Schreibt/löscht man den Sektor, wo man gerade selbst ist, gibts einen 
Hardware-Reset mit Flash-Access-Violation Flag.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Das würde ja einiges vereinfachen, aber widerspricht irgendwie dem von 
mir zitierten User's Manual.

Welchen '430 setzt Du ein? Vielleicht unterscheidet sich der 
Flash-Controller auch etwas von Familie zu Familie ...

von David K. (kresley81)


Lesenswert?

Hallo
Erst mal: Danke für die Antworten. Ich habe das Flash folgendermassen 
initialisiert:

FCTL3 = FWKEY;
FCTL2 = (FSSEL0+ FN1+FWKEY);
FCTL3 = FWKEY + LOCK;

Tatsächlich habe ich eine Accessviolation. Würde das heissen, dass ich 
den bereich lösche, wo ich mich gerade drin befinde? Ich lösche an der 
Adresse 0x1000. die gehört doch zum Infomemory, wo kein Programmcode 
stehen dürfte.

Danke rufus, für die Links. Jetzt verstehe ich, was der Unterschied ist, 
zwischen "Aus dem Flash oder aus dem RAM auf das Flash zugreiffen". Das 
habe ich im Users Guide gelesen, aber ich wurde nicht schlau draus.

Also mein Problem ist: Wenn ich das Segemnt B lösche, indem ich auf die 
Zelle 0x1000 schreibe, tritt die Access violation auf.

von Christian R. (supachris)


Lesenswert?

Ich hab das am F1611 gemacht, hat funktioniert. Allerdings hab ich 
bisher nur im InfoMem gearbeitet damit....

Im Userguide steht auf Seite 5-6 (132):

Initiating an Erase from Within Flash Memory
Any erase cycle can be initiated from within flash memory or from RAM. 
When
a flash segment erase operation is initiated from within flash memory, 
all timing
is controlled by the flash controller, and the CPU is held while the 
erase cycle
completes. After the erase cycle completes, the CPU resumes code 
execution
with the instruction following the dummy write.
When initiating an erase cycle from within flash memory, it is possible 
to erase
the code needed for execution after the erase. If this occurs, CPU 
execution
will be unpredictable after the erase cycle.

von Christian R. (supachris)


Lesenswert?

Was für einen Quarz hast du denn an X1? Du setzt FSSEL0, also ACLK, der 
kommt direkt von X1.

Im User Guide steht aber:

The flash timing generator operating frequency, f(FTG), must be
in the range from ~ 257 kHz to ~ 476 kHz.

Mit einem 32Khz Quarz gehts also nicht.

von David K. (kresley81)


Lesenswert?

Ok, ich habe neue Erkentnisse gewonnen:

Ich hatte einen MCLK von 1MHz (laut Oszilloskop) der Teiler war 4 = 
250kHz

Versuchshalber habe ich jetzt den SMCLK genommen. Den habe ich auf 6Mhz 
eingestellt und durch 16 geteilt = 375kHz.

Mit beiden Taktvarianten war es möglich ein Byte im Flash zu 
überschreiben. Aber beim Löschen des Segments auf 0x1000 trat die 
Accessviolation auf.

ABER: Ich kann das Segment 7 des Mainmemorys löschen, beschreiben und 
auslesen. Ohne Probleme. Das funktioniert. Jetzt frage ich mich: Ist es 
möglich, dass mein Programm im Informationmemory abgelegt wird? Macht 
das AQ430-Tool das? Muss man dem Tool beibringen, dass dort eigentlich 
kein Programmcode stehen dürfte?
Ich kann das AQ430 so einstellen, dass es beim Progrmmieren das 
Informationmemory unbeschrührt lassen soll. Wenn ich das mache, schlägt 
die Programmierung fehl.

von David K. (kresley81)


Lesenswert?

Gerade habe ich im AQ430-Projekt die *.rxc.map gefunden. Vorher ist mir 
die noch nie aufgefallen. Sie enthält unter anderm folgend Zeilen:


SG cstartup$code 0 0x1000 0x1013
SY cstart 0x1000
SY __main_returned 0x1012
SG _idesc 0 0x1014 0x1025
SG main_idata 0 0x1026 0x1027

Wenn dies die Adressen der verschiedenen Programmteile sind, würde dies 
ja bedeuten, dass zB der Startupcode mitten im Informationmemory liegt. 
Und nicht im Main Memory. Ich kenne mich damit aber nicht so gut aus.
Könnte diese Vermutung stimmen? Und hat jemand eine Idee, wie man das 
Programm in den Main-Bereich zwingen kann?

von Kresley81 (Gast)


Lesenswert?

Ok, mittlerweile habe ich es hingekriegt. Der trick ist, dass man im AQ 
den Flash zuerst in Info- und Mainbereich partitionieren muss.

Gruss
David

von Christian R. (supachris)


Lesenswert?

Ui, da hat aber jemand beim Compiler-Hersteller gepennt, das hat ja nun 
wirklich jeder MSP430, beim IAR und GCC ist das immer reserviert.

von Kresley81 (Gast)


Lesenswert?

Das sehe ich auch so. Ich habe mich deswegen beim Entwickler des AQ430 
gemeldet. Der hat mir zurückgeschrieben und gesagt, dass in der nächsten 
Version die Partitionierung standardmässig eingeschaltet sein wird. Er 
will dem Benutzer eben die Möglichkeit geben, den Info auch als 
Mainmemory zu (miss)brauchen und umgekehrt. Man kann beim AQ430-Compiler 
(wie ich jetzt herausgefunden habe) recht einfach jeden Sektor als Info 
oder Main definieren. Das ist ja ganz nett. Nur die Standardeinstellung 
sollte schon so sein wie im MSP Datenblatt beschrieben.

Für die die es interessiert, werde ich Übermorgen (wenn ich wieder am 
Arbeitsplatz bin) hier posten wie man den Bereich pratitioniert.

Viele Grüsse
David

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.