ich stehe vor der Aufgabe, den W25Q128 Flash Chip mithilfe eines STM32 Mikrocontrollers anzusteuern. Ich habe bereits einige Grundlagen erarbeitet (Page lesen/schreiben, Sector löschen/lesen/schreiben, Block löschen/lesen/schreiben), stehe jedoch noch vor einigen offenen Fragen. Ich hoffe, ihr könnt mir dabei helfen, eine effiziente Lösung zu finden. Hier sind meine Anliegen:
Page-Handhabung (Löschen, Lesen, Schreiben):
Mit kleinen Flash Chips konnte ich immer eine Page löschen vor dem beschreiben. Nun musste ich die Erfahrung machen, dass bei den grösseren Chips (ab 64Mbit) diese Funktion nicht mehr möglich ist (Jeden falls steht im Datenblatt nichts dazu). Wenn ich meine bestehende Memory Map übertragen möchte müsste ich einzelne Pages beschreiben können. Damit ich das aber kann müsste ich ebenfalls die Page davor löschen, da ich Sie sonst nicht sauber beschreiben kann. Die kleinste grösse die man nach Datenblatt löschen kann ist ein Sector (16 Pages / 4kB).
Habt ihr evtl. dieses Problem auch schon angetroffen oder habt ihr eine Idee wie ich diese Page möglichst effizient löschen und beschreiben kann? Eine Idee von mir war, dass ich immer nur die ersten Pages eines Sectors verwende (Für einen neue Page den nächsten Sector verwenden), aber dann würde ich halt sehr viel Speicher verschwenden.
Die frage nach dem Page löschen bezieht, sich auf die ersten Pages in denen ich die Einstellungen für das Gerät, Bitmaps für Display usw. speichern möchte. Für den Rest des Speichers wo die Messwerte platziert werden, kann ich auch mit Sector löschen arbeiten.
Ein kleineres Flash kommt übrigens nicht in Frage, da ich sehr grosse Datenmengen speichern möchte und nach meiner Berechnung mind. 8MB benötige.
Falls es jemanden interessiert, die Anwendung ist eine Transport Studie bei der Beschleunigung in allen Achsen, GPS Position und Temperatur gemessen wird, in verschiedenen Intervallen und Zeiträumen.
Ich bin gespannt über eure Erfahrungen oder Vorschlägen.
Also dieses Rad wuerde ich nicht neu erfinden wollen. Ich fress doch einen Besen, wenn's da nicht schon einen ganzen Haufen Software gibt, die auf der einen Seite irgendwas filesystemartiges bereitstellt und auf der anderen Seite auf ein serielles EEPROM werkelt.
Ja wird es sicher geben, die Funktionen dazu habe ich ja schon alle. Meine Frage bezieht sich mehr auf die Logik wie ich damit um gehe.
Eine Weitere Idee die mir noch eingefallen ist, wäre das auslesen eines Sectors ins RAM, die Page im RAM bearbeiten und wieder als gesamten Sektor schreiben. Ich weiss jedoch nicht ob das die effizienteste Methode.
Wenn ich meine bestehende Memory Map
übertragen möchte müsste ich einzelne Pages beschreiben können. Damit
ich das aber kann müsste ich ebenfalls die Page davor löschen, da ich
Sie sonst nicht sauber beschreiben kann.
Das macht mich stutzig. Irgendwas stimmt da nicht; warum sollte man, wenn man Page X beschreiben will, vorher noch Page X-1 plattmachen müssen?
Und was löschst Du, wenn Du die erste aller Pages beschreiben willst?
Soll die erste Page eines Sektors beschrieben werden, wird zuvor der Sektor gelöscht und nur die eine Page beschrieben.
Weitere Pages des Sektors müssten Page für Page geschrieben werden können.
Problematisch ist halt wenn eine Page eines bereits geschriebenen Sektors neu befüllt werden soll. Dann könnte z.B. der gesamte Sektor zu gelesen, gelöscht und anschließend mit den neuen Daten der gesamte Sektor neu geschrieben werden.
Schreiben kann man nur in eine Richtung, meistens 1->0. Nur mit Löschen geht es in die Andere, also 0->1 hier.
In seltenen Fällten kann die Logik invers sein, was bei diesen Chips IIRC nicht der Fall ist.
Du wirst Dein Programm für 4KB Pages umschreiben müssen - und schau Dir auch mal an ob nicht die Endurance - Anzahl der Schreib/Lösch Zyklen - nicht kleiner beim größeren Flash ist.
Übrigens haben auch einige dickere µC 4k Pages im internen Flash.
Wenn man große Datenmengen speichern will, kommt relativ bald eine (Micro)SD in Frage. Die kann immer noch SPI.
Chips (ab 64Mbit) diese Funktion nicht mehr möglich ist (Jeden falls
steht im Datenblatt nichts dazu)
Du hast doch Kommando 0x20 Sector Erase. Mehr kannst du nicht erwarten.
Was haltet ihr davon eine Page mit 256x 0xFF zu beschreiben, das müsste
doch auch wie ein erase funktionierten oder nicht?
Aehem nein. Du solltest dir mal ein paar Grundlagen zur Funktion
von Flashspeicher aneignen. Diese Speicher sind immer intern in
grossen Bloecken/Sektoren organisiert. Du kannst immer nur einen Block
auf einmal loeschen, also auf 0xff bringen. Runterschreiben
geht dann aber auch in kleineren Stuecken.
Also dieses Rad wuerde ich nicht neu erfinden wollen. Ich fress doch
einen Besen, wenn's da nicht schon einen ganzen Haufen Software gibt,
Wie so oft im Leben zahlt sich Faulheit hier mal wieder
nicht aus. Diese QSPI-Flash haben alle Hersteller uebergreifend
grosse Aehnlichkeiten, aber oftmals auch interessante feine
Unterschiede. Da kann man auch schon mal eine Woche mit dem
Debugger zubringen bis man merkt das irgendwo ein Timing
leicht anders ist, ein Bit in einem Register zusaetzlich vorhanden
ist oder nicht, oder man bei dem einen Type ein Register bereits
lesen kann solange noch geschrieben wird, bei dem anderen erst
wenn er fertig ist.
Problematisch ist halt wenn eine Page eines bereits geschriebenen
Sektors neu befüllt werden soll. Dann könnte z.B. der gesamte Sektor zu
gelesen, gelöscht und anschließend mit den neuen Daten der gesamte
Sektor neu geschrieben werden.
Du wirst Dein Programm für 4KB Pages umschreiben müssen - und schau Dir
auch mal an ob nicht die Endurance - Anzahl der Schreib/Lösch Zyklen -
nicht kleiner beim größeren Flash ist.
Ja wahrscheinlich schon. Dann werde ich es so umbauen, dass ich Sectors ins RAM Lese. Beim STM32L475RE den ich verwende habe ich noch 32kB RAM in einem zweiten Sector (RAM2). Dann könnte ich in diesem Teil einen Sector Buffer von 4kB speichern und diesen zurück ins Flash Speichern.
Wenn man große Datenmengen speichern will, kommt relativ bald eine
(Micro)SD in Frage. Die kann immer noch SPI.
Aufgrund von schlechten Erfahrungen in der Vergangenheit, was Zuverlässigkeit der SD-Karten betrifft, bin ich sehr vorsichtig geworden mit dem Einsatz.
Du hast doch Kommando 0x20 Sector Erase. Mehr kannst du nicht erwarten.
Ja den Befehl habe ich. Bei den kleinen hatte ich jedoch auch den Befehl 0xDB Page erase. Das macht das Handling natürlich sehr leicht, Page löschen und danach beschreiben.
Was haltet ihr davon eine Page mit 256x 0xFF zu beschreiben, das müsste
doch auch wie ein erase funktionierten oder nicht?
Aehem nein. Du solltest dir mal ein paar Grundlagen zur Funktion
von Flashspeicher aneignen. Diese Speicher sind immer intern in
grossen Bloecken/Sektoren organisiert. Du kannst immer nur einen Block
auf einmal loeschen, also auf 0xff bringen. Runterschreiben
geht dann aber auch in kleineren Stuecken.
Das stimmt natürlich, manchmal muss man auch den doffen Ideen eine change geben :D
Wie so oft im Leben zahlt sich Faulheit hier mal wieder
nicht aus. Diese QSPI-Flash haben alle Hersteller uebergreifend
grosse Aehnlichkeiten, aber oftmals auch interessante feine
Unterschiede. Da kann man auch schon mal eine Woche mit dem
Debugger zubringen bis man merkt das irgendwo ein Timing
leicht anders ist, ein Bit in einem Register zusaetzlich vorhanden
ist oder nicht, oder man bei dem einen Type ein Register bereits
lesen kann solange noch geschrieben wird, bei dem anderen erst
wenn er fertig ist.
Ich suche nicht nach einer fertigen Lösung. Der Treiber für das Flash ist schon vorhanden. Page lesen/schreiben, Sector löschen/lesen/schreiben, Block löschen/lesen/schreiben usw. habe ich alles getestet, das funktioniert. Ich erarbeite nur noch eine Lösung wie ich die einzelnen Pages beschreiben kann. Da ich wohl oder übel den gesamten sector löschen muss, werde ich es wie folgt machen:
Sektor auslesen in RAM Speichern. RAM befindet isch im 2. Sector des MCU
Da Offset der Pages gleich sein wird, wie im Flash kann ich aus dem 4kB Buffer eine Page auslesen, wie zuvor auch aus dem Flash. Darin werden dann die Daten verändert.
Der zu bearbeitende Sector wir gelöscht
Der 4kB Buffer aus dem RAM2 wird in das Flash geschrieben.
Optional: Page kann wie gehabt aus dem Flash ausgelesen werden und die Werte sollte alle Stimmen wie zuvor auch schon.
Ich denke ihr werdet mir ebenfalls zustimmen, dass dies der sauberste und einfachste Weg sein wird?
Aufgrund von schlechten Erfahrungen in der Vergangenheit, was
Zuverlässigkeit der SD-Karten betrifft, bin ich sehr vorsichtig geworden
mit dem Einsatz.
Naja, es gibt ja auch verschiedene Hersteller und verschiedene
Qualitaeten.
Ich denke ihr werdet mir ebenfalls zustimmen, dass dies der sauberste
und einfachste Weg sein wird?
Diese Teile sind nicht dafuer gedacht das du sie andauernd neu beschreibst und loescht. Du wirst da relativ schnell ein Wearleveling brauchen.
Anstatt sich da den Arsch ab zu programmieren koenntest du
dir auch eine eMMC kaufen wo der Hersteller dir die Muehe bereits
abnimmt.
Naja, es gibt ja auch verschiedene Hersteller und verschiedene
Qualitaeten.
Ja das geht dann so weit, dass auch bekannte Hersteller wie SanDisk oder Kingston Probleme untereinander haben. Bei meinem Einsatzbereich Umwelt, Erschütterung usw. möchte ich auf etwas sichereres gehen.
Diese Teile sind nicht dafuer gedacht das du sie andauernd neu
beschreibst und loescht. Du wirst da relativ schnell ein Wearleveling
brauchen.
Anstatt sich da den Arsch ab zu programmieren koenntest du
dir auch eine eMMC kaufen wo der Hersteller dir die Muehe bereits
abnimmt.
Das ist mit schon bewusst. Im ersten Sector plane ich die Geräte Einstellungen, diese werden im Optimal Fall nie verändert.
In den restlichen Sectoren, planne ich die Daten zu speichern. Diese Werden initial vor der Messung gelöscht und danach erst wieder wenn eine Messung beendet ist und die Daten Ausgelesen sind. Das bedeutet diese Sectoren werden im Optimal Fall alle 1-3 Monate einmal gelöscht.
Löschzyklen nach Hersteller sind min. 100'000 mal pro Sector.
Sollte für meine Anwendung (Laufzeit von 1 Jahr) genügen.