mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik MSP430 Flash


Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,
Ich habe mal wieder ein Problem, ich teh irgendwie auf dem schlauch.
Ich habe ein feld mit 20 char gross ist also 20 Byte. Desie Können zur
Laufzeit über die serielle Schnitstelle verändert werden. Nun sollen
diese im flash gespeichert werden und beim nächten Start wieder geladen
werden. Das problem ist wie kann ich sicherstellen das beim ersten start
(nach dem Flashen) gültige werte im Flash stehen, ich verwende einen
Olimex Jtag adapter und mspgcc. Kann ich der Jtag bestimmte
flashbereiche beschreiben?

gruss Thomas

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@thomas

überleg mal kurz ... wenn du dein programm per jtag ins flash schreiben
kannst, kannst du doch auch bestimmte andere bereiche beschreiben oder
?! *ggg

der "trick" ist folgender : du mußt deinem linker sagen das du einen
bestimmten bereich als eigenen daten-bereich definiert haben willst.
(z.b. OWN_CHAR_DATA)
deine char werte kannst du dann mit diesem daten-bereichs bezeichner in
den flash bereich als variable "reinmappen" (z.b. : OWN_CHAR_DATA char
DeinArray [20]; ) und beim programmieren werden diese daten dann
automatisch in diesen speicherbereich geflasht.
kann dir leider nicht sagen wie das mit dem linker des mspgcc's zu
machen ist, aber i.d.r hast du für die speicherbereiche des msps (wie
auch jeden anderen prozessor) ein fertiges linker-file das du dann
einfach nur editieren mußt.
hoffe das ich deine frage richtig verstanden und richtig beantwortet
habe :-))


gruß

Autor: Johnny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das geht beispielsweise so:

Im C Code:

_attribute_ ((section(".SectionMyFlash")))
const unsigned char MyFlash[] =
{
  0xe4, // 0   erstes byte
  0x0c, // 1   zweites
  0xff, // 2   ...
  0xff, // 3   ...
  0xff, // 4   ...
}

Dann im Linker File diese Zeile (MEMORY):
infomem(rx) : ORIGIN = 0x1000,  LENGTH = 0x0080 /* 128B Infomemory */

Und weiter unten im Linkerfile (SECTIONS):
.SectionMyFlash:
  {
    *(.SectionMyFlash)
    . = ALIGN(2);
  } > SectionMyFlash

Gruss
Johnny

Autor: Johnny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PS Wenn im Linkerfile bereits passende Einträge vorhanden sind, dann
kannst Du diese verwenden. Für das Info memory sollte das der Fall
sein.

Autor: Johnny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Fehlerteufel, so wärs richtig:
Dann im Linker File diese Zeile (MEMORY):
SectionMyFlash(rx) : ORIGIN = 0x1000,  LENGTH = 0x0080 /* 128B
Infomemory */

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
danke für die Infos, nur binn ich mir noch nicht ganz im klaren darüber
wie das anpassen der linkerdatei funktioniert.
Ich habe im mspgcc Verzeichniss die Linkerscripte gefunden, allerdings
gibt es 4 verschiedene für meinen controller:
x .xr *.xn *.xbn

welche muss ich anpassen, und kann ich dieses file im compiler aungeben
wenn es im lokalen verzeichninss liegt? sonst mache ich es so:
 gcc -Os mmcu=msp430x1611 -o xx xx
Ich compiliere immer von hand, ohne makefile, bzw. eine
stappelverarbeitungsdatei.

gruss molla

Autor: taxcon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nun, ich versuche seit langen Daten im AT45DBxx Flash von Atmel
unterzubringen. Ich arbeite mit einem MSP430 über JTAG. Ich weiss das
man zuerst den OPcode auf den SPI Bus bringt, dann 14 Dont care Bit und
letztendlich das Datenbyte. Das ganze ist gekappselt in die
Chipselektion. Irgendwie will das ganze aber nicht richtig
funktionieren, obwohl der richtigen SPI Modus gewählt ist und die
CLK-Polarität stimmt.  Hat jemand ein Vorschlag? C example wären sehr
hilfreich!

MfG taxcon

Autor: Johnny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Taxcon, ich würde vorschlagen, dass Du einen eigenen Thread für Deine
Frage eröffnest. Sonst wird es ziemlich unübersichtlich und Deine Frage
hat ja mit der Eingangsfrage nichts zu tun.

Thomas, ich bin leider auch nicht so der GCC Freak, aber ich habe in
meinem Makefile folgende Anweisung gefunden, welche das lokale
Linkerspript mit der Endung .x verwendet:
-Xlinker -T NAME_DES_LINKERSCRIPTS.x

Du solltest diese Anweisungen einfach an deinen Compileraufruf im
Batchfile anhängen können.

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jonny, danke funktioniert, aber ich habe gleich eine Frage die ich noch
nicht ganz verstehe ;-)

wenn ich den array initialisiere
_attribute_ ((section(".SectionMyFlash")))
const unsigned char MyFlash[] =
{
  0xe4, // 0   erstes byte
  0xff, // 4   ...
}
,wird dass doch bei jedem Programmstart, bzw. jedem resett gemacht oder
sehe ich das falsch? Denn ich möchte die daten nur nach dem Flashen
initialisieren danach sollen sie die werte beibehalten, die per rs232
reingeschrieben werden.

danke, gruss Thomas

PS: ich habe nach infos gegooglet, habe aber leider nichts dazu
gefunden, die mspgcc Dokumentation finde ich sowieso etwas spärlich.

Autor: Johnny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja da hast Du recht. Ich finde die Dokus auch zimelich spärlich und
kompliziert. Eigentlich benutze ich den MSP430 nur aus beruflichen
Gründen ;-)

_attribute_ ((section(".SectionMyFlash")))
Das da gibt an, in welcher Section sich das Nachfolgende befindet.
Weil es sich im Flash befindet, wird es beim flashen in diesen Speicher
geschrieben.

Bei der Deklaration des Arrays ist das "const" sehr wichtig. Wenn Du
das const weglässt, dann wird der startup code den Inhalt des Arrays
vom Flash ins RAM kopieren, da der Compiler davon ausgeht, dass man den
Inhalt des Array modifizieren will.
Du willst den Inhalt zwar modifizieren, aber das geht ja nicht so
einfach, da er sich im Flash befindet.
Somit musst Du dann erst das ganze Infomemory "von Hand" löschen und
komplett neu beschreiben.
Das "const" zeigt dem compiler also an, dass in diesen Speicher nicht
direkt geschrieben werden kann und wenn Du das aus versehen trotzdem
tust, kommt eine entsprechende Fehlermeldung beim kompillieren.

Beim Aufstarten wird nichts ins Flash geschrieben. Das "__attribute__
((section(".SectionMyFlash")))" legt nur fest, an welcher
Speicheradresse sich das nachfolgende Array befindet.

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
aha, ok
wenn ich dich richtig verstehe wird also nur beim flashen der Inhalt
des const char* in den Flash geschrieben. Wenn ich jetzt anschliessend
den Flashbereich überschreibe, bleibt dieser auch erhallten und wird
nicht beim Reset neu initialisiert.

Ich habe die ausahl des MSPs schon etwas bereuht, da er eigentlich
etwas zu schwach auf der brust ist, bzw. meine Programmierung zu
ineffizient ist ;-).

Danke für die hilfe, werde es gleich mal versuchen.
gruss Thomas

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich muss gleich noch eine Frage nachschieben, wenn ich einen 2. Array in
dem FLashSegment anlegen will kann ich das mit der gleichen Attribute
anweisung machen, oder muss ich mir einen neuen Bereich festlegen?

gruss Thomas

Autor: Johnny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja genau. Die so wie oben deklarierten Daten werden nur beim Flashen per
JTAG ins Flash geschrieben. Nachher passiert dort nichts mehr damit,
ausser wenn Du manuell, im programmcode das entsprechende flashsegmend
löscht und neu beschreibst.
Ich habe auch solche Anwendungen und die funktionieren gut so.
Du musst einfach bedenken, dass nur ganze Flashsegmente gelöscht werden
können und nicht einzelne Bytes.

Ein 2. Array oder mehrere Arrays in dieselbe section zu legen ist kein
Problem. Der Compiler legt sie dann automatisch hintereinander.

Wie gesagt musst Du einfach zur Kenntnis nehmen, dass beim löschen per
programmcode jeweils das ganze Flashsegment (siehe Hardware manual)
gelöscht wird mit allen Daten darin.

Autor: Johnny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh noch ein kleiner Tipp:
Während Du per Programmcode im Flash hantierst (löschen oder
schreiben), dann unbedingt die Interrupts deaktivieren mit _DINT(); und
nachher wieder mit _EINT(); aktivieren. Ansonsten kann und wird der uC
immer öfters abstürzen bei diesen Vorgängen.

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

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
jetzt hät ich nochmal ein anliegen, ich glaub langsamm ich binn unfähig
;-)
Warum funtioniert ich die Funktion nicht?
Wenn ich 10 als value übergebe steht 0 2 2 0 0, wenn 1 dann 1 0 1 0 1
und bei FF wird gar nichts gemacht?

gruss Thomas

Autor: szimmi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hiho,
löscht Du vorher den Flash? Schreiben hat nämlich die unangenehme
Eigenschaft, dass die Bits nur von 1 nach 0 kippen und nicht
umgekehrt.Bevor Du neue Werte in die Zelle schreibst, immer löschen (es
sei denn, Du schreibst nach dem Löschen ständig FF's in die Zellen,
dann kannst Du Dir das sparen :-)

Autor: szimmi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ups, haette den Quelltext lesen sollen. Wie ich sehe, löscht Du vorher.
Also vergiss meinen vorigen Beitrag erstmal...

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo, kann es sein dass es an meiner Memorymap liegt???
MEMORY
{
  text   (rx)     : ORIGIN = 0x4000,  LENGTH = 0xbfe0
  data   (rwx)    : ORIGIN = 0x1100,   LENGTH = 0x2800
  vectors (rw)    : ORIGIN = 0xffe0,      LENGTH = 0x20
  bootloader(rx)  : ORIGIN = 0x0c00,  LENGTH = 1K
  infomem(rx)    : ORIGIN = 0x1000,  LENGTH = 256
  dataflash(rx)    : ORIGIN = 0x1000,  LENGTH = 0x80
  infomemnobits(rx)  : ORIGIN = 0x1000,      LENGTH = 256
}

Muss ich infomem und infomemnobits raus nehmen? Ich habe es versucht
bekomme dann aber immer seg faults, wo kann ich da meory abknapsen ?

gruss Thomas

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe auch diese versucht selbe symptopme
MEMORY
{
  text   (rx)     : ORIGIN = 0x4000,  LENGTH = 0xbfe0
  data   (rwx)    : ORIGIN = 0x1100,   LENGTH = 0x2800
  vectors (rw)    : ORIGIN = 0xffe0,      LENGTH = 0x20
  bootloader(rx)  : ORIGIN = 0x0c00,  LENGTH = 1K
  infomem(rx)    : ORIGIN = 0x1080,  LENGTH = 0x80
  dataflash(rx)    : ORIGIN = 0x1000,  LENGTH = 0x80
  infomemnobits(rx)  : ORIGIN = 0x1080,      LENGTH = 0x80
}

gruss Thomas

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
so ich hab mein Problem jetzt eruieren können, wer lesen kann ist klar
im vorteil. Ich habe dass busy Flag nicht abgefragt.
Allerdings steht iM Datasheet nichts zum SMCLK, nur als kommentar im
Beispiel code. muss dieser runtergesetzt werden?

gruss Thomas

Autor: szimmi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hiho nochmal,
was mich etwas wundert ist die Tatsache, dass Du das Busy-Flag abfragen
musst. Läuft die Flash-Routine aus dem RAM?
Wenn sie aus dem Flash läuft, braucht man das Busy-Flag lt.Datenblatt
nicht abfragen.

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

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich habe jetzt die 2 Zeilen für die abfrage eingefügt und es
funktionier einwandfrei. Der SMCLK braucht auch nicht heruntergesetzt
werden es muss nur der Divisor für den Flashcontroller angepasst
werden.
Jetzt hab ich mal eine doofe frage wie erkenne ich ob die Routine im
Flash oder RAM läuft?

gruss Thomas

P.S: wenn es jemand interresiert habe ich die Funktionierende Funktion
angahängt.

Autor: Johnny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Cool das es funktioniert :-)
Wenn Du den Programmcode nicht manuell ins RAM kopierst und mittels
einem Pointer darauf springst, dann läuft es ganz normal vom Flash.

Programmcode aus dem RAM laufen zu lassen macht beim MSP430 eigentlich
nur Sinn, wenn Du z.B. einen Bootloader programmierst, welcher das
gesamte Flash (inkl. sich selber) löschen/beschreiben muss.

Autor: Marcel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
muss ich die Taktrate des SMCLK runtersetzen: Ja ->

TI schreibt für den Zugriff auf den Flash eine Takrate von ~ 257 kHz
bis ~ 476 kHz vor. Die Taktrate für den Flash stammt entweder vom ACLK,
MCLK oder SMCLK. Um auf die geforderten Grenzen für die Taktraten zu
kommen teilt der Flash Timing Genrator mit einem Teiler z.B. den MCLK.
Kapitel 5.3.1

Gruß Marcel

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.