Hallo zusammen,
ich möchte das Flash eines STM32F103 als Eeprom-Ersatz (AN2594)
verwenden. Im Datenblatt und sonstigem ST-Dokus habe ich
widersprüchliche Aussagen gefunden. Einmal soll es nicht erlaubt sein,
während der Schreibphase aufs Flash zuzugreifen (z.B. um in einem
anderen Task/Interrupt/sonstwas Code auszuführen). Ein anderes Mal liest
man, dass es hier keine Einschränkung geben soll.
Ich verwende ein 128k-Derivat, das nur eine Bank(?) hat. Liegt hier
evtl. der Unterschied zu Derivaten mit mehr als einer Bank(?). (Bin mir
unsicher, ob Bank der richtige Begriff ist).
Hat jemand hierzu eine eindeutige Aussage? Ich würde natürlich gerne
hören, dass es niemals nicht kein Problem ist, wenn während des
Schreibvorganges zeitgleich anderer Code ausgeführt wird. :-)
Ich will/kann nämlich nicht die restliche Codeausführung für viele
Millisekunden "anhalten".
Danke,
Martin.
>Ich will/kann nämlich nicht die restliche Codeausführung für viele>Millisekunden "anhalten".
Dann kauf dir ein SPI-FRAM und hühner da nicht im Flash rum.
Wo stammen deine widersprüchlichen Information (Link)? Wenn die Zahl der
Schreibzugriffe gering ist, sollte es gehen. Da man das Flash, in dem
das Programm abgearbeitet wird, nicht beschreiben kann, erfolgt der
Zugriff von einem Programm aus, welches im RAM läuft.
P. S. 'holger' ist ein Schwätzer. Nicht weiter beachten.
Kuhle Wampe schrieb:> Wo stammen deine widersprüchlichen Information (Link)?
Das ist leider das Problem mit dem irgendwann/irgendwo Gelesenem - man
weiß es nicht mehr. Ich habe nur noch im Hinterkopf, dass da was war.
Wenn nichts war, umso besser.
> Wenn die Zahl der> Schreibzugriffe gering ist, sollte es gehen. Da man das Flash, in dem> das Programm abgearbeitet wird, nicht beschreiben kann, erfolgt der> Zugriff von einem Programm aus, welches im RAM läuft.
Nein, das ist nicht das Problem. Man muss bei den STM32 die
Flashroutinen nicht ins RAM kopieren. Habe gerade nochmal in der
StdPeripheralLib von ST nachgesehen. Offensichtlich können die STM32
gleichzeitig aus dem Flash den Code ausführen und einen anderen Block(?)
oder Bank(?) löschen. Die sperren dort auch keine Interrupts oder sowas.
Aber gibt mir das die Gewissheit, dass es nicht doch zu Problemen kommt,
wegen irgendwas, das ich nicht bedenke/kenne?
Mein reales Problem ist, dass zur gleichen Zeit anderer Code ausgeführt
werden soll/muss. Da ich nicht auf externes Eeprom ausweichen möchte,
frage ich nach einer Aussage von jemandem, der das sicher weiß.
Danke.
Martin schrieb:> Aber gibt mir das die Gewissheit, dass es nicht doch zu Problemen kommt,> wegen irgendwas, das ich nicht bedenke/kenne?
Trenne Blocks in Programm- und Daten-Blocks. Natürlich kannst du aus
einem Block, den du gerade beschreibst, keine Programmfunktionen
ausführen. Also in dem Block besser garkein Programm unterbringen, sonst
wird das sehr unübersichtlich und fehleranfällig. Der Programmierer
meint oft, das und das könnte zu der und der Zeit ja nicht passieren,
aber das sind mit die am schwierigsten zu findenden Fehler, wenn man
sich da täuscht. Und das soll gelegentlich vorkommen.
Georg
Du kannst überall in den Flash schreiben, Interrupts müssen aber vorher
gesperrt werden. Wärends des eigendlichen Schreibvorgangs hält die CPU
automatisch an, bis der Vorgang beendet ist.
PM0068 Programming manual STM32F10xxx XL-density Flash programming
During a write operation to the Flash memory, any attempt to read the
Flash memory will stall the bus. The read operation will proceed
correctly once the write operation has completed. This means that code
or data fetches cannot be made while a write/erase operation is ongoing.
Dual bank architecture
The XL-density Flash memory features a dual bank architecture based on
bank 1 (512Kbytes) and bank 2 (up to 512Kbytes). This architecture
supports the RWW (readwhile-write) capability. This means that while a
read or program operation is performed in a bank, the other bank can be
accessed for another operation (read or program) without the need to
wait for the End of Operation on the first bank.
D.h: Mit nur einer Code in RAM kopieren und aus dem RAM laufen, speziell
beim Löschen.
Danke für die Rückmeldungen, aber jetzt haben wir wieder den Salat. Es
gibt verschiedene, widersprüchliche Meinungen. :-)
Vielleicht liegt das daran, dass nicht klar ist/war, um welches Derivat
es sich bei mir eigentlich genau handelt. => STM32F103RBT6, also ein
medium-densitiy Teil. Scheinbar unterscheiden sich die einzelnen
Derivate doch in Details voneinander?!?
Steve schrieb:> PM0068 Programming manual STM32F10xxx XL-density Flash programming
[...]
> D.h: Mit nur einer Bank den Code in RAM kopieren und aus dem RAM laufen,> speziell beim Löschen.
Das scheint nicht für meinen STM32F103RBT6 zu gelten, denn der gehört
nicht zur XL-density Serie.
Außerdem kann ich mit der von dir zitierten Stelle aus PM0068 auch nicht
deine Schlussfolgerung nachvollziehen.
Detlef Kunz schrieb:> Du kannst überall in den Flash schreiben, Interrupts müssen aber vorher> gesperrt werden. Wärends des eigendlichen Schreibvorgangs hält die CPU> automatisch an, bis der Vorgang beendet ist.
Das mit dem automatischen Anhalten ("stall") kenne ich auch von einem
STM8. So verstehe ich auch den Text aus PM0075:
1
During a write operation to the Flash memory, any attempt to read
2
the Flash memory will stall the bus. The read operation will proceed
3
correctly once the write operation has completed. This means that code or
4
data fetches cannot be made while a write/erase operation is ongoing.
Daher erscheint mir deine Erklärung für die passendste. Danke.
Frage : Aber wieso muss dabei eine Interruptsperre aktiv sein?
/* If program operation was failed, a Flash error code is returned */
20
if(EepromStatus!=FLASH_COMPLETE)
21
{
22
returnEepromStatus;
23
}
24
}
25
}
26
}
Dieser Code wird in EE_Init ausgeführt, sobald erkannt wurde, dass ein
Block gültig ist (VALID) und der andere Block auf RECEIVE_DATA steht.
Also dann wenn die Daten von einem Block zum anderen umkopiert werden
müssen.
Frage: Wieso wird da immer fix mit Adresse Base+6 verglichen? Das
bewirkt doch nur, dass immer die erste Variable aus der
Variablenliste/VirtAddr-Liste NICHT in den neuen Block geschrieben wird.
Wieso will man das hier so? Oder was habe ich nicht verstanden?
AN2594: Link:
http://www.st.com/web/en/catalog/tools/FM147/CL1794/SC961/SS1743/LN1734/PF257846
Danke,
Martin.
Martin schrieb:> Frage : Aber wieso muss dabei eine Interruptsperre aktiv sein?
Ups, ja das ist nur für die Unlock-Sequenz nötig, damit die niemand
unterbricht.
Weitere Frage:
Angenommen eine Page ist bereits komplett gelöscht und ich lösche diese
nochmals mit Erase. Geht das trotzdem aufs Material? Sprich zählt das
als Programmiervorgang, der auf die Lebensdauer geht, obwohl die Bits
eigentlich elektrisch nicht gelöscht werden (müssen)?
Hintergrund: AN2594 löscht ja bei EE_Init immer die gerade nicht in
Verwendung befindliche Page grundsätzlich beim Hochfahren - auch wenn
diese bereits im gelöschten Zustand ist.
Danke dir, Detlef. :-)
Gruß,
Martin.
Martin schrieb:> Angenommen eine Page ist bereits komplett gelöscht und ich lösche diese> nochmals mit Erase. Geht das trotzdem aufs Material? Sprich zählt das> als Programmiervorgang, der auf die Lebensdauer geht, obwohl die Bits> eigentlich elektrisch nicht gelöscht werden (müssen)?
Eine sehr gute Frage.
Die Frage ist ja, was macht die Flashzelle kaputt?
Das ist der Durchgang der Elektronen duch die Isolierung (also auch das
Schreiben sollte zerstörent wirken und man spricht ja auch von
write/erase cycles).
Wenn die Page leer ist, und daraus folgend keine Elektronen tunneln
müssen, dann sollte eigentlich nicht passieren.
Aber letztendlich können das nur die Entwickler der jeweiligen
Flash-Technologie beantworten.
Mein Algorithmus testet vor einem PageErase ob die Page leer ist, und
wenn leer, dann wird nicht nochmal gelöscht.
Detlef Kunz schrieb:
> Martin schrieb:>> Angenommen eine Page ist bereits komplett gelöscht und ich lösche diese>> nochmals mit Erase. Geht das trotzdem aufs Material? Sprich zählt das>> als Programmiervorgang, der auf die Lebensdauer geht, obwohl die Bits>> eigentlich elektrisch nicht gelöscht werden (müssen)?> Mein Algorithmus testet vor einem PageErase ob die Page leer ist, und> wenn leer, dann wird nicht nochmal gelöscht.
Das könnte auf die Datensicherheit gehen. Wenn der Löschvorgang im
richtigen Moment abgebrochen wurde, sind die Zellen nur halb gelöscht,
gerade genug, um beim ersten Lesen nicht aufzufallen. Nach dem
Beschreiben sind dann mehr Bits auf 0 als man möchte.
Deswegen schreibe ich ein Flag-Byte im frisch gelöschten Sektor. Wenn
nach einem Reset dieses Flag nicht stimmt, lösche ich nochmal. Wenn es
zu stimmen scheint, ist es evt. auch nur halb programmiert, aber das ist
in dem Fall egal.
Keine Ahnung, ob das wirklich soviel nützt wie ich glaube.
Schaulus Tiger schrieb:> Das könnte auf die Datensicherheit gehen. Wenn der Löschvorgang im> richtigen Moment abgebrochen wurde, sind die Zellen nur halb gelöscht,> gerade genug, um beim ersten Lesen nicht aufzufallen. Nach dem> Beschreiben sind dann mehr Bits auf 0 als man möchte.
Das ist eine Frage des Protkolls.
Das könnte ja auch beim Schreiben passieren.
Wenn ein Vorgang nicht abgeschlossen werden konnte, ist die Page als
korrupt zu betrachten.