Hallo!
Ich suche ein einfaches Beispiel, wo Daten ins Flash gespeichert
werden!?
Ich arbeite mit dem STM32F103VDT6 und dem uVision von Keil. Unser Motor
EC45 Flat 36V / 50W fährt einfach von A nach B mit einer Last von 180Kg
an einem Schneckengetriebe. Bei der Ersten Fahrt wird der Weg gemessen.
Dies soll bei Stromausfall erhalten bleiben.
Leider habe ich noch nie mit dem Flash gearbeitet. Bin die Datenblätter
am Durchlesen. Aber ein kleines Beispiel würde mir sicher sehr helfen.
Auf der ST Site gibts eins, aber nicht zu diesem uP!
Danke und Gruss!
M.B.
Erstmal musst du im Linker File eine neue Section anlegen, die du für
die Nutzdaten verwendest ( ich denke eine Memory Page wird dafür locker
reichen ).
Die Variable wird in diese Section gepackt und kann auch schon
problemlos gelesen werden.
Um sie zu beschreiben, musst du
1) Flash unlocken
2) Die ganze Page löschen
3) Die Variable beschreiben
4) Flash wieder locken
(für jeden diese Punkte gibt es im FLASH teil der Std Lib Funktionen)
So hat es bei mir zumindest unter CooCox schonmal funktioniert.
Hallo AVerr!
Danke für deine Hilfe! Ich habe jetzt ein Beispiel gefunden fürs EVAL
Board MCBSTM32C. Ich besitze dieses Board. Ich schau mir auch die Lib
an. Aber das mit den Sections habe ich noch nicht begriffen, wo/wie ich
dies tun muss!?
Danke und gruss!
M.B.
Da man den Flash nur seitenweise beschreiben kann, muss man eine
komplette memory page für die Nutzdaten reservieren.
Die Größe und Adresse der pages entnimmst du dem Reference Manual.
In meinem Fall ( STM32F103C8 ) waren es 64 pages a 1K, ab 0x08000000.
D.h. die letzte Page ( die ich für Daten benutze ) fängt bei 0x0800FC00
an.
Das Linker Script besteht aus 2 Teilen ( meist in den Dateien memory.ld
und/oder link.ld ... je nach Entwicklungsumgebung ):
1) MEMORY Definition:
1
MEMORY
2
{
3
rom (rx) : ORIGIN = 0x08000000, LENGTH = 0x0000FC00
Hier wird das vorhandene Memory festgelegt.
rom ist in diesem Fall das restliche Flash ( Pages 1-63 ) und rom1 die
letzte memory page, die für die Daten verwendet wird.
2) Section Definition:
1
SECTIONS
2
{
3
.mydata :
4
{
5
*(.mydata)
6
} > rom1
7
[...]
8
}
Hier wird eine Section namens .mydata definiert, sodass alle Variablen,
welche in diese Section wandern im Memory Bereich rom1 landen.
Zu guter letzt wird die Variable in die section .mydata gepackt:
Ich habe mein gefundenes Beispiel angehängt! Darun sehe ich niergends
ein Hinweis, dass eine Section ausgewählt wurde! Ich bin kein
Schnelldenker, das kapier ich noch nicht! bei uVision kann ich dies doch
Target options --> Linker einstellen oder? Auch sehe ich im Beispiel
nicht, welche Daten abgespeichert werden.
Sorry und danke!
>Darun sehe ich niergends ein Hinweis, dass eine Section ausgewählt wurde!
Unbedigt brauchst du das nicht. Nur dann, wenn dein Programm annähhernd
das ganze Flash aufbraucht. Es ist nur wichtig, dass sich deine Flash
Daten nicht mit dem Programm überschneiden.Wenn du die Pages ganz am
Ende des Flash für deine Daten nutzt, passiert das sowieso nicht. Der
Linker bewirtschaftet (defaultmässig) das Flash von 0 an.
Grüsse
Wenn du den Flash mehr oder weniger als EEPROM Ersatz benutzen willst,
schau dir auch mal die EEPROM Emulationsbeispiele bei ST in der Sotware
Library an. Hab ich in meinen Motorkontroll Projekten auch schon
erfolgreich benutzt.
Schreiben des Flash geht natürlich nicht so oft wie ein richtiges
EEPROM, du solltest also haushalten oder evtl. doch ein externes EEPROM
in Betracht ziehen, wenn die Schreibvorgänge häufig stattfinden.
ok, danke für den Tip! Ich hoffe ich kapier es bald :-)
Das Ziel ist, dass einmal am Tag die Zurückgelegte Strecke abgespeichert
wird und mittels Service -Kit per CAN ausgelesen werden kann.
Also Ich muss immer
das Flash unlocken,
die page löschen,
die Variable beschreiben,
das flash locken.
Der Linker setzt die Variable dann automatisch an nullter Stelle im
Flash, so muss ich also auch nur die page 0 löschen?
Gibt es eine Kontrollmöglichkeit, um sicher zu sein, dass es geklappt
hat?
Gewisse teilen ja den Flashbereich und speichern alles doppelt?
Danke und Gruss!
M. B. schrieb:> Der Linker setzt die Variable dann automatisch an nullter Stelle im> Flash, so muss ich also auch nur die page 0 löschen?
Der Linker setzt sie nicht an Stelle 0, dort liegt der Einstiegspunkt in
dein Hauptprogramm. Vom Löschen von Page 0 ist DRINGEND abzuraten.
Es stimmt, man kann auch ohne Sections arbeiten, allerdings besteht dann
halt die Gefahr, dass auf der Page, auf der man arbeitet, weitere Daten
abgelegt werden. Aber wie Gebhard Raich (geb) gesagt hat, ist das eher
unwahrscheinlich.
Die saubere Lösung wäre natürlich, alles fein säuberlich in Sections
aufzuteilen, damit nichts passieren kann. Für den Testbetrieb kann man
das aber auch weglassen.
> Gibt es eine Kontrollmöglichkeit, um sicher zu sein, dass es geklappt> hat?
Naja, wenn es funktioniert, weisst du es ;)
Du kannst dir die map-File ansehen, die der Compiler erstellt. Darin
stehen die Adressen aller deiner Variablen nachdem der Linker sie
verteilt hat.
Als erstes solltest du rausfinden wie viele pages dein Controller hat
und wie groß diese sind.
Dann suchst du die Adresse der letzten page raus und probierst
testweise, dort daten abzulegen und auszulesen. Wenn das klappt, kannst
du dich immer noch um das Sectioning kümmern wenn du willst.
Schaue Dir auch den "Backup RAM" einmal näher an. Per Batterie kann man
dort 42 Worte für 10 Jahre speichern.
Der STM32F4xx hat sogar 4KB Backup-RAM und kann wie ein gewöhnlicher RAM
genutzt werden.
Wenn man die Batterie heraus nimmt, sind natürlich die Daten auch weg.
Mit parallel 100µF kann man aber schon einige Sekunden für den
Batteriewechsel überbrücken.
Hier wird die Seite beginnend bei 0x0800FC00 gelöscht und an der Stelle
0x0800FC00 werden 4 byte geschrieben ( der Inhalt der Variable data ).
Man könnte nun mittels eines Zeigers darauf zugreifen:
Ich muss jetzt aber alle Variablen einzeln ins flash laden und jede
Variable kommt in eine neue Page, hab ich das richtig verstanden?
Was hat es eigentlich mit dem Information Block auf sich. Ich benötige
ja nur das Main Memory!
Vielen Dank und Gruss!
M.B.
Mit dem Debugger habe ich das Programm laufen gelassen.
Und jetzt schaue ich im Memory an der Adresse 0x0807F800: Wert: 0B000000
Die Variable, die ich abgespeichert habe oder wollte hat den Wert 2!?
Gruss!
Mein Fehler!! Die Variable hat den Wert 11. Also hat es geklappt!!
So jetzt muss ich noch aus dem Flash lesen bzw. laden.
Vielen Dank und freundliche Grüsse!
M.B.
M. B. schrieb:> jetzt habe ich alle Daten, die ins Flash gehören in einn Struct gefasst.> Ich muss jetzt aber alle Variablen einzeln ins flash laden und jede> Variable kommt in eine neue Page, hab ich das richtig verstanden?
Ich habe es anders verstanden (FLASH_ErasePage z.B. habe ich im zip aber
auch nicht gefunden).
Statt FLASH_ProgramWord kann man ja bestimmt auch eine ganze page
schreiben. Oder in einer Schleife ein word nach dem anderen.
Wahrscheinlich gibt es auch eine Funktion, mit der man einen Block mit
variabler Größe schreiben kann. Oder schreibt sich die, wie gerade
beschrieben, mit einer Schleife selbst.
ja, das Beispiel im Zip gab nicht so viel her, habe die StandLib
hinzugeführt. Da finde ich aber auch nur FLASH_ErasePage und kein
anderer Löschbefehl. Zum Daten aus dem Flash laden, gibts da keinen Read
Befehl?
Danke und Gruss!
M.B.
Lutz schrieb:> Oder in einer Schleife ein word nach dem anderen.
Genau so wird das gemacht.
Dein Struct schreibst du Word für Word in diese eine Page, hast ja 2KB
Platz.
Ansonsten wäre das ja ein ziemlich großer Flashverbrauch.
Die Lib hat nur Funktionen zum schreiben von Word und HalfWord.
M. B. schrieb:> Zum Daten aus dem Flash laden, gibts da keinen Read> Befehl?
Nein, weil es ja mittels Pointern ziemlich einfach ist ( siehe oben ).
Wenn du eine Linker Section für die Variable hinbekommst, kannst du sie
sogar ganz regulär lesen.
jetzt mal ne andere Frage: Im Datenblatt steht, dass der STM32F103VDT6
384kByte Flash zur Verfügung hat. Wenn ich die Pages 0 - 255 a 2kB
zusammenzähle ergibt dies ja 512kB und das nur das Main Memory.? Was
Stimmt jetzt?
Vielen Dank für Eure Hilfe!
Die Adresse 0x0807F800 wäre die Startadresse der page 255.
Weil dein Controller aber nur 192 pages hat, ist die Adresse der letzten
Seite 0x0805F800 ( = 0x08000000 + 191 * 2048 ).
Habe es im Datenblatt gefunden "up to..". Verstehe ich aber nicht,
sorry!
2.3.3 Embedded Flash memory
The high-performance Flash memory module has the following key features:
● For XL-density devices: density of up to 1 Mbyte with dual bank
architecture for readwhile-
write (RWW) capability:
– bank 1: fixed size of 512 Kbytes
– bank 2: up to 512 Kbytes
● For other devices: density of up to 512 Kbytes
● Memory organization: the Flash memory is organized as a main block and
an
information block:
– Main memory block of size:
up to 128 Kbytes × 64 bits divided into 512 pages of 2 Kbytes each (see
Table 6)
for XL-density devices
up to 4 Kb × 64 bits divided into 32 pages of 1 Kbyte each for
low-density devices
(see Table 2)
up to 16 Kb × 64 bits divided into 128 pages of 1 Kbyte each for
medium-density
devices (see Table 3)
up to 64 Kb × 64 bits divided into 256 pages of 2 Kbytes each (see Table
4) for high-density devices
up to 32 Kbit × 64 bits divided into 128 pages of 2 Kbytes each (see
Table 5) for connectivity line devices
Wenn ich mir diesen Ausschnitt aus dem Datenblatt ansehe, so würde ich
doch annehmen, dass ich 256 Pages habe --> high-density device
Liege ich da falsch oder lese ich das Datenblatt falsch? 192 Pages wäre
schon logischer!
danke für die Formel!
Also, dein Controller ist laut Datenblatt aus der High-density
performance line.
Von dem gibt es mehrere Versionen, z.B. deine STM32F103VDT6 mit 384 kB
Flash oder auch STM32F103VET6 mit 512 kB Flash ( nur das E ist hier in
der Bezeichnung anders ).
Nun könnten ST zu jeder dieser Versionen eine eigene Tabelle machen, das
wäre aber zu viel Arbeit.
Daher geht man im Reference Manual von der Vollbestückung ( in diesem
Fall 512 kB ) aus, für alle anderen Modelle muss man ein wenig rechnen.
In Abschnitt 3.3.3 vom Reference Manual steht:
1
Memory organization: the Flash memory is organized as a main block and an
2
information block:
3
[...]
4
up to 64 Kb × 64 bits divided into 256 pages of 2 Kbytes each (see Table 6) for
5
high-density devices
6
[...]
Also wieder das "up to".
Da dies 512 kB Flash entsprechen würde, musst du halt deine 192 Pages a
2 kB selbst ausrechnen und kommst wie oben erklärt zur Adresse der
letzten page.
Die wichtigsten Informationen hier sind nur die page size und der Start
( 0x08000000 ). Den Rest kann man dann selbst berechnen.
Super danke, jetzt hats geklappt! Musste sicher sein, dass...
>> Also, dein Controller ist laut Datenblatt aus der High-density>>performance line.
...ist, aber trotzdem nur 192 Pages hat.
Vielen Dank für Deine Geduld und Hilfe!
Gruss
M.B.
Jetzt interessiert mich nur die Variable "cal_OK". Wie kann ich jetzt
mittels Pointer auf die einzelne Variable im struct im Flash
draufzeigen? Das habe ich noch nicht ganz geschnallt!
Dein Beispiel oben greift doch auf die ganze Page des flash zu. oder?
Danke und Gruss!
M.B.
Diese Berechnung:
> int x = (sizeof(tSetup2) / sizeof(int));
und diese Schleife
> for(i=0;i<x;i++)> {> FLASH_ProgramWord(FLSHBSEADRPG192, pData[i]);> }
können funktionieren.
Zwischen dem BOOL und dem ersten int ist vermutlich ein Loch von 3 Byte.
Wenn dies auf eine andere Architektur portiert würde oder jemand im
Makefile global -fpack-struct einstellt oder dem struct ein
_attribute_ ((packed)) hinzufügt, dann fliegt es Dir vermutlich um die
Ohren.
Eine korrekte Serialisierung im Sinne eines definierten "byte streams"
ist das nicht.
Es funktioniert nicht immer die erste Variable BOOl erfasst er fast
immer, die restlichen bytes sind immer null:
0x0805F800: 01 00 00 00 FF FF FF FF FF FF FF FF ect.
Obwohl die Variablen im Struct Setup2 mit Werten gefüllt wurden.
Was könnte das jetzt sein.
Roland H. schrieb
> Eine korrekte Serialisierung im Sinne eines definierten "byte streams">ist das nicht.
AVerr schrieb:> Kein wunder, du schreibst alle deine Daten an die selbe Adresse.> FLASH_ProgramWord(FLSHBSEADRPG192 + i*sizeof(uint32_t), pData[i]);
^^^^
Sicher?
Frage: Versuchst du mit pData[i] auf ein struct-member zuzugreifen?
Etwas Ordnung bzw. Weitblick sollte dazu führen, daß du eine globale
volatil-Variable (man weiß ja nie, was noch dazukommt oder wo man es
noch nutzt) einführst, die dir die nächste freie Speicherstelle in
deiner section anzeigt. Sinnvollerweise muß die natürlich selbst in die
section deines Flash gelegt werden, um auch nach einem reset noch ihre
Funktion erfüllen zu können; so quasi als Inhaltsverzeichnishilfe.
Da fällt einem bei Nachdenken sicher noch etwas mehr sinnvolle Struktur
für diese section ein ...
Roland H. schrieb:> Zwischen dem BOOL und dem ersten int ist vermutlich ein Loch von 3 Byte.
Wenn BOOL hier als uint8_t definiert ist, ja. Also sollte man ... oder
... .
Hi Leute,
ich beschäftige mich momentan mit exakt dem gleichen Problem, benutze
aber einen stm32f205vg und muss ca. 1kb Daten speichern. Hardware ist
vorgegeben, einen eeprom kann ich also nicht hinzufügen.
Meine Frage dreht sich um die Aufteilung des Flashspeichers:
4x16kb
1x64kb
7x128kb
Wenn ich die erste Page verwende würde (afaik) der Startpointer in
meinen Speicherbereich zeigen anstatt auf den Startupcode. Die letzte
Page will ich nicht nehmen da mein Code ziemlich viel Platz des Flashs
belegen wird und mir 128kb Platz für 1kb Daten einfach zu schade ist. Am
liebsten wäre es mir wenn ich dem Linker mitteilen könnte dass er die
zweite Section für die Daten nutzen soll und den Code darum herum
platziert. Leider habe ich keinen Ansatz wie ich dafür das Linkerfile
modifizieren muss.
Als Linkerfile verwende ich aktuell das File für das Atollic True Studio
das in der StdPeriphLib von ST
(http://www.st.com/web/en/catalog/tools/PF257898) enthalten ist.
Vielen Dank für eure Hilfe im Voraus,
viele Grüße
Alex
Hi,
wie ich die letzte Page des Flashspeichers nutzen kann ist mir klar,
mein Problem ist jedoch dass die letzte Page mit 128kB für mein 1kB
Daten überdimensioniert ist, vor allem in Anbetracht des doch recht
umfangreichen Codes der noch mit auf den Flash muss. Deshalb würde ich
gerne eine der kleinsten Pages verwenden, bevorzugt eine der ersten mit
16kB.
Nur wie bringe ich dem Linker bei dass er für den Programmcode z.B. Page
1-3&5-12 benutzen soll, also im Prinzip um meine gespeicherten Daten
herum mappt?
Danke für die Antwort im Voraus,
viele Grüße
Alex
Eine Page ist je nach Device entweder 1KByte oder 2KByte groß. Dem
linker musst du nicht beibringen, sondern "nur" in deinem Programmcode
auf die gewünschte Page zugreifen. So in der Art:
Das Problem ist wie beschrieben dass ich glaube das der stm32f205 eben
keine pagesize von 1-2kB besitzt, sondern die riesigen 128kB im Falle
des letzten "Sector" (Terminologie im Datenblatt, denke aber das damit
Pages gemeint sind). In dem Falle kann ich nicht die letzte Page
verwenden sondern muss eine aus der Mitte herausgreifen und weis nicht
wie ich dem Linker das bei bringen soll.
Liege ich mit meiner Interpretation richtig?
http://www.st.com/st-web-ui/static/active/en/resource/technical/document/reference_manual/CD00225773.pdf
Seite 53
Vielen Dank für die Antworten im Voraus,
viele Grüße
Alex
Ich habe so etwas ähnliches bereits realisiert, da mir das EEPROM
Emulation Beispiel von ST nicht wirklich gefallen hat. Ich teile es
gerne. Eine Beschreibung ist nicht dabei und ist nicht ausgiebig auf
Bugs getestet. Gespeichert wird ein Byte/Word im Flash, um die
Überschreibzyklen zu reduzieren, also bei einer Page von 1024 Byte
stehen 512 Bytes zu Verfügung.
Das kann doch nicht funktionieren. Woher weiss der Compiler denn, dass
ich mit "0x0800FC00" eine Adresse meine? Gibt es keine Spezielle
Lesefunktion beim STM32F4? Page und solche Dinge gibt es beim F4 nicht.
Das Ganze habe ich für ein Firmware-Update auf dem F103 schonmal
gebraucht, sollte auf dem F4xx aber genauso funktionieren:
Falls du mit dem ARM GCC arbeitest, kannst du im C-Code Variablen in
Sektionen mappen:
Beispiel:
Damit findet der Linker später die Variable in der entsprechenden
"Sektion". Jetzt musst du dem Linker nur noch klar machen, wo die
Sektion liegen soll. Das geht im Memory Mapping / Linker-File:
rom (rx) : ORIGIN = 0x08001110, LENGTH = 0x0000EEF1
8
/* ... */
9
}
10
11
SECTIONS
12
{
13
.staticrom_reset :
14
{
15
KEEP(*(.static_rom_vect .static_rom_vect.*))
16
*(.static_rom_reset .static_rom_reset.*)
17
} > staticrom_reset
18
19
/* ... */
20
.isrvectors :
21
{
22
KEEP(*(.isr_vector .isr_vector.*))
23
} > isrvectors
24
.softwareversion :
25
{
26
*(.software_version .software_version.*)
27
} > softwareversion
28
29
.text
30
{
31
/* ... */
32
} > rom
33
/* ... */
34
}
Problematisch wird es aber, .text in zwei Sektionen zu teilen. Ich hatte
alles was vor 0x1000 war in extra Sektionen gepackt und .text erst ab
0x1110 anfangen lassen.
Ich will aber nicht die Variablen in so eine selbst definiert Sektion
schreiben, sondern aus beliegen Speicherstellen lesen können, um Z.B
zeigen zu können, dass mein Flashvorgang geklappt hat. Und um Linkerfile
schreibt die Keil IDE schon herum. Vielleicht kann ich da in den
Einstellungen etwas übergeben. Ok, mal sehen...
@Phantomix:
Vielen Dank für Deinen Post, Du bringst die Lösung für den GCC auf den
Punkt. Mit einem entsprechenden Linkerscript bekommt man eine
EEPROM-Emulation auf dem F4 sauber mit jeder beliebigen Codegröße hin:
sector0 (rx) : ORIGIN = 0x08000000, LENGTH = 0x00004000
feeprom (rx) : ORIGIN = 0x08004000, LENGTH = 0x00008000
rom (rx) : ORIGIN = 0x0800C000, LENGTH = 0x00074000
sector0 enthält nur die Vektoren.
feeprom enthält Flashseiten 1 und 2.
Rom enthält alle anderen Festwerte und liegt in den großen
Flashpages.
Mit diesem Setup kann man mit nur knapp 3x16kB ein EEPROM emulieren. Ist
bei den F4 meist kein Beinbruch und spart das externe EEPROM.
Hallo zusammen,
ich beschäftige mich momentan auch damit, Daten während der Laufzeit in
den Flash-Speicher zu schreiben.
Ich verwende einen STM32F429 mit der Entwicklungsumgebung µVision und
dem Compiler von Keil.
Ich schreibe Daten aus einem Array ab einer bestimmten Adresse im
Flash-Speicher.
Ich schreibe die Daten dazu Wort für Wort in den Speicher ohne vorher
den Speicherbereich zu löschen.
Er beschreibt auch die gewünschten Adressen allerdings sind die Daten im
Flash verändert gegenüber den Werten im Array.
Beispielsweise soll 0xC8 geschrieben werden und im Flash-Speicher steht
0xC0 oder 0x48 oder statt eines Wertes 0x1AC2 (Array) steht 0x1A82 im
Flash-Speicher. Also irgendwie scheinen die Werte leicht verändert zu
sein.
Folgender Code verwende ich zum Schreiben der Daten:
/* Enable the flash control register access */
FLASH_Unlock();
/* Calculate the end address */
u32l_start_address = u32param_start_adr;
u32l_end_address = u32param_start_adr + u32param_length;
/*Check if the start-address is valid */
if (u32l_start_address >= ADDR_FLASH_START)
{
/*Check if the end-address is valid */
if (u32l_end_address <= ADDR_FLASH_END)
{
/* Program the user Flash area word by word */
while (u32l_start_address < u32l_end_address)
{ /* Write data to flash */
if (FLASH_ProgramWord(u32l_start_address, *u32param_data) ==
FLASH_COMPLETE)
{ /* Increment address to write */
u32l_start_address = u32l_start_address + 4;
/* Increment the address of the data field to save */
u32param_data++;
}
else
{
/* Error occurred while writing data in Flash memory, set error
*/
u32l_error_code = ERR_WRITING_FLASH;
}
}
}
else
{
/* Illegal end-address, set error*/
u32l_error_code = ERR_END_ADR_FLASH;
}
}
else
{
/* Illegal start-address, set error*/
u32l_error_code = ERR_START_ADR_FLASH;
}
/* Lock the Flash to disable the flash control register access
(recommended
to protect the FLASH memory against possible unwanted operation) */
FLASH_Lock();
Also das Schreiben auf die Adressen klappt, und die Adressen stimmen
auch, lediglich stimmt der Inhalt nicht.
Ich würde mich über alle Hilfen freuen.
Grüße vom Flasher
Hallo,
Daten in ein nicht gelöschtes Flash schreiben ist wie auf eine schon
bemalte Tafel zu malen - man kann immer nur weiss hinzufügen, nie jedoch
schwarz und das dabei herauskommende Bild sieht nicht so aus wie man es
sich vorstellt.
Flash kann nur mit "0"en beschrieben werden. Das Löschen vorher sorgt
dafür, dass nur noch "1"en im Flash stehen (die mit "0"en überschrieben
werden können) und keine "0"en (die nicht mit "1"en überschrieben werden
können). Schreibst Du z.B. Deine C8 in eine Zelle, in der vorher schon
F7 stand, wirst Du eine C0 zurücklesen.
Also: Flash vor dem neubeschreiben immer löschen.
Schöne Grüße,
Martin
Hallo Martin,
vielen Dank für deine Antwort, sowas habe ich mir schon gedacht,
allerdings ist es blöd einen ganzen Sektor zu löschen, ich würde gerne
nur Teile eines Sektors löschen.
Doch in der Standardbiblithek habe ich noch keine derartige Funktion
gefunden.
Den gewünschten Speicherbereich mit Nullen zu beschreiben wird nicht
gehen oder?
Oder gibt es eine Möglichkeit einen Speicherbereich von z.B. 100Bytes
zu löschen?
Grüße
der Flasher
Flasher schrieb:> Oder gibt es eine Möglichkeit einen Speicherbereich von z.B. 100Bytes> zu löschen?
Nein, nur ganze Pages sind möglich! Warum stört Dich das Löschen??
Hi Flasher,
Du kannst problemlos jeden "gewünschten Speicherbereich mit Nullen zu
beschreiben".
Weiterführende Tipps, z.B. wie man auch wieder 1en in die Sektoren
bekommt, findest Du in den Handbüchern (RM0090 oder auch in AN3969).
Grüße,
RoyalFlush
Hallo Sepp,
die Pages sind 128kByte groß (zumindest die im oberen Speicherbereich)
ich verwende aber für verschiedene Daten verschiedene Bereiche
(Konfigurationsdaten, Fehler, Logging-Daten und Zeitdaten, etc.) wenn
ich jetzt in einen Sektor mehrere Daten ablegen will, will ich davor ja
nicht alle Daten wieder löschen.
Und so viele Datenarten und Code wie ich verwende, gibts nun mal nicht
genügend Sektoren.
Natürlich kann ich kleinere Sektoren verwenden, aber die kleinsten haben
nun mal auch min. 16kByte.
Oder gibt es noch ne andere Lösung für meine Daten?
Grüße
der Flasher
Hallo,
Du musst den Flash nicht löschen, um Daten hineinzuschreiben, Du musst
ihn nur löschen, bevor Du Daten überschreibst. Auf diese Weise
funktioniert die EEProm-Emulation, die man z.B. in App-Note AN2594 unter
http://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/CD00165693.pdf
findet. Mit dieser Methode können viele Variablen in eine Flash-Page
gelegt und auch überschrieben werden, wobei es nur bei jedem x-ten
Schreibzugriff zu einem Flash-Erase kommt.
Wenn Du zusätzlich diese Emulation an den Anfang des Flash legst,
verschwendest Du auch nicht viel Speicher, da hier die Pages
entsprechend kleiner sind, wie Du schon festgestellt hast. Minimum sind
2 Pages für 1 bis 8000 (16-Bit-)Variablen.
Schöne Grüße,
Martin
Hallo Martin,
also soweit alles verstanden, was die Speicherung betrifft.
Jetzt habe ich nur folgendes Problem: Ich möchte die kleinsten Sektoren
des Flash-Speichers benutzen (Sektor0 bis Sektor3 mit jeweils 16kB und
Sektor4 mit 64KB)
Das Programm beginnt momentan bei 0x08000000, jetzt habe ich in der
µVision-Umgebung den Beginn des Programms auf 0x08020000 verschoben, die
Länge angepasst im Programm habe ich das Headerfile angepasst, in dem
beispielsweise Definitionen zum Flash-Speicher-Start und zum Ort der
Vektortabelle angegeben sind ebenfalls auf die neue Adresse des
Programmcodes angepasst.
Aber jetzt läuft mein Programm gar nicht mehr, wenn ich es wieder
zurückstelle geht es wieder.
Was muss ich beachten um mein Programm (meine Interrupt-Vektortabelle)
im Speicher nach hinten in den ersten 128kB-Sektor zu schieben?
Hab ich noch was vergessen, oder geht es ganz anders?
Grüße
der Flasher
> die Vektor-Tabelle muss immer am Anfang liegen (im Sektor 0)
Nicht zwingend, man kann jede beliebige Speicherposition für die Tabelle
benutzen, wichtig ist, dass am Anfang des Flashes steht:
0x08000000 Stack-Size
0x08000004 Reset-Vector
Auf die Weise kann man sich bspw einen eigenen Bootloader bauen, und die
Ziel-Anwendung bringt ihre Vectortabelle selbst mit.
Hallo zusammen,
wenn Daten überschrieben werden sollen, die z.B. in der Mitte einer Page
liegen, davor befindliche Daten aber erhalten bleiben sollen, müssen
dann alle zu erhaltenden Daten zunächst zwischengespeichert werden und
nach dem Erase wieder geschrieben werden?
Grüßle
Hm... ich war "ideelich" auf dem Weg da eine Art FAT System anzulegen
ähnlich wie bei SD Karten, aber da rappelt man sich ja nen Ast mit den
Lösch und Schreibzugriffen...
Ich tausche die letzten 8 Pages meine Flashes gegen 16kiB internes
EEPROM - jemand interessiert^^
Jasson schrieb:> Ich tausche die letzten 8 Pages meine Flashes gegen 16kiB internes> EEPROM - jemand interessiert^^
Wenn dir das alles zu heikel ist, nimm doch einen externen EEPROM wie
z.B. den 24C128 mit 16kB oder den 24C256 mit 32kB. Die halten auch mehr
Schreibzyklen aus und sind bei Bedarf leicht auszutauschen - oder eben
wirklich eine SD Karte.
Gibt es eine Möglichkeit eine eigene Section zu definieren, die Mitten
in einer anderen liegt, so dass die andere Section sich drumherumlegt?
Gemeint ist das so:
1
rom (rx) : ORIGIN = 0x08000000, LENGTH = 0x0000FE00
Sinn ist dass ich ein paar Variablen an eine feste Adresse im Hexfile
bekomme, so dass ich "von außen" (etwa in einem Firmwareupdatetool) z.B.
die Version aus der Datei lesen kann. Wennn man rom1 ans Ende legt, hat
man immer eine bin-Datei die so groß wie das Flash ist und zwischen der
Applikation und dem rom1 Bereich ist alles leer.
Stefan