Hallo,
ich plane grade ein Gerät mit EEPROM. Natürlich möchte ich dabei
load-leveling benutzen, um die Lebenszeit des Gerätes zu verlängern.
Ich habe mich ein bisschen umgeschaut und nichts wirklich überzeugendes
gefunden, daher habe ich mir ein paar Gedanken gemacht.
Im Grunde geht es ja darum, die Daten in einen chronologische Ordnung zu
bringen. Man könnte natürlich den Zeitpunkt jedes mal mitschreiben, aber
wenn man die Daten in festen Intervallen misst, dann reicht es wohl den
Startzeitpunkt der Messung zu erfassen. Ich denke hier an Geräte bei
denen periodisch Daten gesammelt werden - Logger aller art,
Tonaufnahmegeräte...
Die Probleme treten ja größtenteils da auf, wo eine Art Liste angelegt
werden muss, um festzuhalten, welche Bytes/Pages in welche Reihenfolge
gehören. Ich hatte folgende 4 Ideen, die an sich auch naheliegend sind:
a) Verwendung einer Tabelle, im RAM, die, vor dem Ausschalten des
Gerätes in den Speicher an eine Bekannte Position geschrieben wird. In
der Tabelle stehen die zufällig gewählten Bereiche in einer Reihenfolge.
Nachteile:
- Falls das Gerät abstürzt sind die Daten evtl. weg.
- Der Block in dem Die Tabelle liegt wird ungleichmäßig beansprucht.
b) Verknüpfung der Daten jeweils über "Zeiger" am ende einer Page/eines
Datenblocks.
Nachteile:
- hoher Speicherverbrauch (Zeigergröße * genutze Blockgröße) gerade
wenn die Daten nur 8-bit pro Zuordnungseinheit betreffen.
- Start/Ende müssen über Iteration gefunden werden. Alternativ kann Sie
auch mitgespeichert werden, das ist aber nicht zwingend. Falls man das
tut, gilt der 2. Nachteil unter a)
- die nächste Position muss vor dem Schreiben des eines Blocks bekannt
sein.
- kein "Wahlfreier", sondern nur sequentieller Zugriff möglich.
c) Man verwendet eine art pseudo-RNG, der jede zahl von 0 bis
Speichergröße-1 genau einmal produziert. Das Datenende ist gleich der
Anzahl der Iterationen. )Falls ein solcher RNG existiert/gegeben ist,
dann kann die letzte Iteration auch aus der Addresse, des letzten
beschriebenen Blocks berechnet werden.)
Nachteile:
- der seed muss extra-gespeichert werden
- das # der Iteration muss evtl. extra gespeichert werden.
d) Man geht ähnlich, wie bei Adam7 und Konsorten vor. Man fängt also an
zb. jeden 128. Block zu beschreiben. Erreicht man das Ende beschreibt
man jeden 64. Block der kein 128. Block ist, usw. Um nun ein
load-leveling zu erreichen, wird der erste zu beschreibende Block, an
dem also die Daten ausgerichtet werden um 0-127 Positionen (oder müssen
das 126 sein? egal..) verschoben.
Nachteile:
- etwas viel Rechenaufwand gegen ende.
- Offset muss gespeichert werden.
Die Vorteile habe ich jetzt nicht aufgelistet. Vielleicht fällt jemanden
noch eine bessere Methode ein, oder ein paar entscheidende
Vor-/Nachteile. Evtl. kann das auch ins wiki übergehen, als komplette
Übersicht?
Außerdem würde mich interessieren, ob es Pseudo-RNGs gibt, die jede Zahl
in einem bestimmten Zahlenbereich nur einmal ausgeben. Ich kenne so eine
Funktion nicht. (Stichwort?)
Beste Grüße,
Kermit
Ich verstehe Deinen Aufwand nicht ganz. Beim Wear levelling kommt es
darauf an, dass nach hunderttausend oder einer Million
Schreiboperationen pro Platz jeder Speicherplatz gleich oft beschrieben
wurde. Wichtig ist nur, dass jeder gleich oft drankam, nicht in welcher
Reihenfolge.
Wenn Du also das EEProm 1 Mal vollschreibst, ist es am Schluss egal, ob
es linear nacheinander beschrieben wurde oder kunstvoll in möglichst
komplizierten Mustern. Nach 1x Vollschreiben wurde jeder Speicherplatz
einmal genutzt, egal nach welcher Methode, und vom Wear Levelling her
betrachtet besteht kein Unterschied mehr zwischen linear und z.B. Deiner
RNG-Methode. Dito nach dem vollständigen 2., 3., ... nten Beschreiben.
Du kannst also ruhig linear vollschreiben (die Records hintereinander
runterschreiben und wrappen), wenn Du nur drauf achtest, dass immer am
nächsten Platz weiter geschrieben wird. Methoden dafür sind nicht
schwierig. Man kann z.B. einen Zähler im Record mitlaufen lassen oder
immer vor Beschreiben des leeren Platzes den nächsten freien Platz
löschen und den gelöschten Bereich als Eintrage/Ende-Markierung nehmen.
Nachtrag: Ich bin bei meiner Antwort davon ausgegangen:
kermit der frosch schrieb:> Ich denke hier an Geräte bei> denen periodisch Daten gesammelt werden - Logger aller art,> Tonaufnahmegeräte...
also von einem Datenstrom mit fester Reihenfolge. Kompliziertere
Algorithmen ergeben erst bei nicht gleichverteilten wahlfreien
Schreibzugriffen Sinn (einer Halbleiterdisk z.B.).
Ich habe wahrscheinlich auf mein Problem mit einem zu großen Hammer
draufgeschlagen.
Hc Zimmerer schrieb:> wenn Du nur drauf achtest, dass immer am> nächsten Platz weiter geschrieben wird. Methoden dafür sind nicht> schwierig. Man kann z.B. einen Zähler im Record mitlaufen lassen oder> immer vor Beschreiben des leeren Platzes den nächsten freien Platz> löschen und den gelöschten Bereich als Eintrage/Ende-Markierung nehmen.
Im Grunde geht es mir nicht um riesige Records in ca. Page-größe,
sondern eher um ca. 16 bis 32, vllt. 64 bit pro Record. D.h., dass ein
fortlaufender counter so groß sein muss, wie die Speichergröße in
bit/byte, geteilt durch die Datensatzgröße in bit/byte. Bei extremen
8bit/Datensatz und 1Mbit Speichergröße, bräuchte man doch schon ca. ein
word (?) zum adressieren. Wenn ich mir nun vorstelle, ich habe einen
flash-rom mit 8Mbit.. - klar, hier würde ein B-tree fs oder ähnliches
wahrscheinlich schon in betracht kommen.
Immer den nächsten freien Platz zu beschreiben scheint mir keine
optimale Lösung zu sein, da man zb. im EEPROM, dann eine längere
Schreibzeit hat. Dadurch hat man auch doppelt so viele Schreibvorgänge.
Man könnte natürlich auch den EOD-marker in das letzte Byte/Bit der Page
setzen. Dann muss man natürlich noch einen Wrap-Around erkennen können.
Wenn du meinst, dass der Zähler die Zahl der Durchgänge/Wrap-Arounds
zählen soll, dann passt das natürlich. Somit ließe es sich auch
realisieren, alte Daten beim Wrap-Around gleich zu überschreiben. Wenn
man sich nun noch den Anfang markieren könnte, dann braucht man auch
keinen chip-erase mehr. Auch der Zähler kann dann ein bool(=1bit) sein,
der bei jedem Wrap-Around einmal toggelt.
Wunderbar, vielen Dank für den Gedankenanstoß, ich werde das erstmal
ausarbeiten und vielleicht einmal die ein oder andere Methode
simulieren.
Man könnte den Schreibaufwand reduzieren wenn man sichergehen kann, dass
das Gerät rechtzeitig mitbekommt, dass ihm gleich der Strom entzogen
wird (beispielsweise in dem man den Controller puffert und ihn die
Versorgungsspannung überwachen lässt, oder eine Nutzereingabe
voraussetzt). Dann müsste er nur vor dem Abschalten den letzten+1
Datensatz löschen und könnte sonst den nächsten Datensatz immer direkt
überschreiben und sich die Position im RAM merken und beim Neustart die
Leerstelle suchen.
Geht nicht unbedingt, aber wenn die Stromversorgung nur selten
unterbrochen wird und der zusätzliche Schaltungsaufwand möglich
erscheint...
Die Schreibzugriffe cache ich sowieso bis auf page-größe, das sollte man
ja auch tun. So eine Brown-Out-Schaltung ist natürlich schick, und ich
würde sowas auch bauen, weil es - denke ich - der optimalst weg bzgl.
Schreibzugriffe/Nutzdatendichte ist. Leider arbeite ich aber gerade an
einem Projekt, bei dem jeder µA und jede ms im Active Mode gespart
werden muss. Das Gerät soll über kurze Zeit, aber auch über mehrere
Jahre hinweg eingesetzt werden können. Ein zusätzlicher, relativ großer
Stützkondensator und anderes Hühnerfutter stören also schon.
kermit der frosch schrieb:> Immer den nächsten freien Platz zu beschreiben scheint mir keine> optimale Lösung zu sein, da man zb. im EEPROM, dann eine längere> Schreibzeit hat.
Nicht unbedingt. Bei den AVRs z.B. kann man Löschen und Schreiben
trennen und hat dann etwa je den halben Zeitverbrauch. Unterm Strich
(nächsten Record-Platz löschen, dann derzeit freien beschreiben) kommt
man in etwa auf dieselbe Zeit wie beim kompletten Neubeschreiben eines
einzigen Datensatzes. BTDT.