Forum: Mikrocontroller und Digitale Elektronik Flash Chip mit FAT16 formatieren


von Holger K. (holgerkraehe)


Lesenswert?

Hallo zusammen

Ich möchte meinem kleinen Mikrocontrollersystem etwas zusätzlichen 
Speicher spendieren.

Dazu möchte ich ein externes SPI Flash verwenden.
Da dieses ja in Pages organisiert ist und deshalb ein byte-orientierter 
Zugriff eher mühsam ist, und auch dann eine organisation der Daten 
notwendig ist, habe ich an ein FAT16 gedacht.

Mein Konzept sieht folgendes vor:

Flash könnte z.B. dieses hier sein:
http://www.mouser.com/ds/2/198/25WD020-040-258523.pdf
2MBit NOR Flash

Dieses würde ich dann am Controller per SPI anschliessen.

Um den Chip auszulesen, würde ich die Library von ELM-Chan verwenden:
http://elm-chan.org/fsw/ff/00index_e.html

Wobei ich die fullFeaturered version verwende, damit ich auch Dateien 
erstellen kann.

Nun, in der Theorie sehe ich dass so, dass ich bei der Library von elm 
Chan lediglich die I/O Funktionen schreiben muss.

In diesem Fall wäre dies:
http://elm-chan.org/fsw/ff/en/dwrite.html
http://elm-chan.org/fsw/ff/en/dread.html

Die funktionen enthalten beide einen "Sektor"
Dieser kann, je nach konfiguration von FatFS, zwischen 512 und 4096Bytes 
sein.

Nach meinem Verständnis, hat der verlinkte Flash Sektoren mit 4Kbit.
Dies würde soweit ja passen, wenn ich diese denn direkt auslesen kann.
Beim Schreiben hingegen, kann das Flash lediglich 256Bytes auf einmal.

Nun ist mir klar, dass ich das alles abfangen kann und entsprechende 
Funktionen schreiben kann, welche mir die Daten dann wieder korrekt 
zurechtbiegen.

Da ich jedoch auch noch etwas Lernen möchte, habe ich nun ein paar 
Fragen an die Experten unter euch:

Wie ich gesehen habe, hat nich jedes Flash die gleiche Sektoren grösse.
Die Chips mit mehr speicher haben oft 64Kbit oder mehr.
Ist es üblich, dass man das Programm "Hardcodiert" an einen bestimmte 
Flash anpasst? bzw. gibt es eine elegante Lösung, ohne grossen Aufwand 
mehrere Sektorengrössen zu unterstützen?

Damit FatFS überhaupt etwas mit dem Inhalt des Flashs anfangen kann, 
muss dieses ja zuerst noch einen MBR und eine leere FAT16 haben.

Leider habe ich im Internet noch nicht viel dazu gefunden, wie denn eine 
leere FAT16 aussieht.

Könnte mir eventuell noch jemand ein paar Tipps geben, wo bei meinem 
Vorhaben die Stolperfallen sind?

Danke :)

von Stefan F. (Gast)


Lesenswert?

https://de.wikipedia.org/wiki/File_Allocation_Table#Aufbau

Unter Limux kannst du mit dem mkfs Befehl ein leeres Filesystem anlegen 
- zum Beispiel in einer Datei, die du anschließend 1:1 in den Flash 
Speicher überträgst.

Die erste Stolperfalle wird sein, dass bei jedem Schreibzugriff das 
Inhaltsverzeichnis aktualisiert wird und das ist dann immer wieder der 
selbe Speicherblock. Der wird als erstes wegen Verschleiß kaputt gehen.

Mach Dir mal über wear-levelling Gedanken, das ist momentan wichtiger, 
als das Filesystem.

von Holger K. (holgerkraehe)


Angehängte Dateien:

Lesenswert?

Stefan U. schrieb:
> Mach Dir mal über wear-levelling Gedanken, das ist momentan wichtiger,
> als das Filesystem.

Ich müsste vielleicht noch dazu sagen, dass während der Lebensdauer 
meines Geräts, nur sehr wenig auf das Flash geschrieben wird.

Im Flash liegen vielmehr statische Daten, welche öfters mal ausgelesen 
werden.

Evtl. werden auch ab und an mal ein paar Messwerte abgelegt, etwa alle 
paar stunden einmal.

Das wäre dann Pro tag: 24/3 = 8 * 365 = 2920 Schreibzyklen pro Jahr
Bei 5 Jahren: 14600 Schreibzyklen.

Das würde dicke reichen, zumal niemals 5jahre lang alle 3 Stunden ein 
File geschrieben wird.

Laut Datenblatt kann der Chip mind. 100'000 Schreibzyklen.

Stefan U. schrieb:
> Unter Limux kannst du mit dem mkfs Befehl ein leeres Filesystem anlegen
> - zum Beispiel in einer Datei, die du anschließend 1:1 in den Flash
> Speicher überträgst.

Interessant, gefällt mir, dieser Ansatz!
Ist das dann Speichergrössen unabhängig?

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

@Holger Krähenbühl (holgerkraehe)

>Nun, in der Theorie sehe ich dass so, dass ich bei der Library von elm
>Chan lediglich die I/O Funktionen schreiben muss.

>In diesem Fall wäre dies:
>http://elm-chan.org/fsw/ff/en/dwrite.html
>http://elm-chan.org/fsw/ff/en/dread.html

So in etwa.

>Die funktionen enthalten beide einen "Sektor"
>Dieser kann, je nach konfiguration von FatFS, zwischen 512 und 4096Bytes
>sein.

Hmm, bei meinem letzten intensiven Studium von FatFs waren nur 512 
Bytes/Sektor möglich.

>Beim Schreiben hingegen, kann das Flash lediglich 256Bytes auf einmal.

>Nun ist mir klar, dass ich das alles abfangen kann und entsprechende
>Funktionen schreiben kann, welche mir die Daten dann wieder korrekt
>zurechtbiegen.

Nimm lieber einen Flash der auch 512 BYtes schreiben kann, sonst wird es 
unnötig stressig und du must einen 512 Byte Buffer in deine 
Zugriffsfunktionen einbauen.

>Wie ich gesehen habe, hat nich jedes Flash die gleiche Sektoren grösse.
>Die Chips mit mehr speicher haben oft 64Kbit oder mehr.
>Ist es üblich, dass man das Programm "Hardcodiert" an einen bestimmte
>Flash anpasst?

Jain. Man packt das alles in #define und stellt damit die unterste 
Schicht der Zugriffsfunktionen passen ein.
Die Luxusvariante liest vorher den Flash aus und stellt sich automatisch 
daruf ein.

>Damit FatFS überhaupt etwas mit dem Inhalt des Flashs anfangen kann,
>muss dieses ja zuerst noch einen MBR und eine leere FAT16 haben.

Ein lösbares Problem.

>Leider habe ich im Internet noch nicht viel dazu gefunden, wie denn eine
>leere FAT16 aussieht.

Leer ;-)
Die FAT ist mit 0xFFFF voll, bis auf ein paar wenige Ausnahmen am 
Anfang.
Ausserdem kann FatFs ein Medium selber formatieren. Du musst also nur 
den MBR manuell draufbringen.

von Stefan F. (Gast)


Lesenswert?

> Unter Limux kannst du mit dem mkfs Befehl ein leeres Filesystem anlegen
(sollte Linux heissen)

Interessant, gefällt mir, dieser Ansatz!
Ist das dann Speichergrössen unabhängig?

Ja. Die gewünschte Größe gibt man als Kommandozeilenaparameter an.

von Holger K. (holgerkraehe)


Lesenswert?

Falk B. schrieb:
> Nimm lieber einen Flash der auch 512 BYtes schreiben kann, sonst wird es
> unnötig stressig und du must einen 512 Byte Buffer in deine
> Zugriffsfunktionen einbauen.

Ich brauche ja onehin einen Buffer für einen Sektor.
Sonst kann FatFS ja gar nicht arbeiten.

Schreiben mit 256Byte wäre das kleinere Übel, denn da schreibe ich dann 
einfach zweimal hintereinander.

Das Problem ist, dass die meisten Flash nur Erase mit 4Kbit zulassen.
Eine 0 schreiben kann man ja nicht. Deshalb mus mann ja zuerst immer 
eine gesamte Page, daher 4Kbit, löschen.

Damit die Daten dann nicht verloren sind, muss ich diese ja auch noch 
zwischen speichern.

Also Schreiben von 256Byte würde bedeuten:

4Kbit einlesen, Daten maskieren, 4Kbit schreiben.

von Michael U. (amiga)


Lesenswert?

Hallo,

vielleicht ist das hier was für Dich:
https://github.com/pellepl/spiffs

Auf dem ESP8266 benutzt es sich einfach und bisher zuverlässig.
Wie groß der Aufwand für eine Anpassung ist, kann ich aber nicht 
einschätzen.

Gruß aus Berlin
Michael

von Holger K. (holgerkraehe)


Lesenswert?

Vielen Dank für deinen Vorschlag.
Wenn möglich, würde ich jedoch lieber ein System wie Fat16 verwenden.

Vielleicht weiss ja noch jemand etwas über die verschiedenen eigenheiten 
von Flashchips etwas zu schreiben.

Insbesondere habe ich noch nicht wirklich einen Überbrlick darüber,
Wie viele Daten ich auf einmal lesen muss.

von Falk B. (falk)


Lesenswert?

@  Holger Krähenbühl (holgerkraehe)

>> Nimm lieber einen Flash der auch 512 BYtes schreiben kann, sonst wird es
>> unnötig stressig und du must einen 512 Byte Buffer in deine
>> Zugriffsfunktionen einbauen.

>Ich brauche ja onehin einen Buffer für einen Sektor.
>Sonst kann FatFS ja gar nicht arbeiten.

Der ist aber schon im FatFs drin!

>Schreiben mit 256Byte wäre das kleinere Übel, denn da schreibe ich dann
>einfach zweimal hintereinander.

Wenn du sowieso nur wenig schreiben willst, ist FATFs nicht wirklich 
nötig oder gar sinnvoll. Die meisten Daten sind statisch udn read only, 
das kriegt man mit eienm Array mit Startsektor und Länger deutlich 
einfacher hin.
Für das gelegentliche Schreiben kann am einfache, sektorbasierte 
Funktionen schrieben, wenn es sein muss auch mit einfachem Waer Leveling 
in Form eines Ringpuffers.

>Das Problem ist, dass die meisten Flash nur Erase mit 4Kbit zulassen.
>Eine 0 schreiben kann man ja nicht. Deshalb mus mann ja zuerst immer
>eine gesamte Page, daher 4Kbit, löschen.

Also sinnvoll im RAM puffern und nur gelegentlich in den Flash 
schreiben.

>Damit die Daten dann nicht verloren sind, muss ich diese ja auch noch
>zwischen speichern.

https://www.mikrocontroller.net/articles/Speicher#EEPROM_Schreibzugriffe_minimieren

>Also Schreiben von 256Byte würde bedeuten:

>4Kbit einlesen, Daten maskieren, 4Kbit schreiben.

Ist so meist nicht sinnvoll. Dann eher deinen Speicher teilen. Flash für 
die ROM-Daten, einen kleinen FRAM für die RW-Daten. Dann musst du kein 
Pufferkonzept umsetzen. FRAM kann SEHR oft beschrieben werden.

https://www.mikrocontroller.net/articles/Speicher#FRAM

von Holger K. (holgerkraehe)


Angehängte Dateien:

Lesenswert?

Danke Falk, für deine Antwort.

Ich sehe ein, dass es momentan den Anschein macht, als ob ein FatFS 
nicht unbedingt das sinnvollste zu sein scheint.

Oftmals ist es ja so, dass man im voraus noch nicht genau weiss, wass 
man später noch alles für features benötigt.

Deshalb werde ich hier dennoch auf ein FatFS setzen.
Zumal mit die Funktionen der Chan Lib bereits sehr gut bekannt sind und 
vorhanden sind.

Ein eigenes "FileSystem" zu schreiben, erscheint mir hier als 
Mehraufwand gegenüber dem bereits ausgiebig getesteten ElmChan.

Hab hier noch was gutes gefunden:
http://www.stf12.org/developers/FatFS.html

Diese verwenden ebenfalls FatFS mit einem deutlich grösseren Flash Chip.
Dieser hat 128Kbit Physikalische Sektoren.

Laut deren Beschreibung, haben sie nur um den FlashChip verwenden zu 
können, und um die damit verbundenen 128k zwischen zu speichern, ein 
externes Ram angeschlossen.

Das nenne ich mal overkill.
Soweit würde ich jetzt nicht gehen.

Im schlimmsten fall, brauche ich dann halt noch 4Kbyte für einen 
Physikalischen Sektor. Dies ist verkraftbar. Evtl. gibt es auch Flash 
Chips mit kleineren Sektoren.

Mir war es wichtig zu erfahren, ob ich mit meinem Vorgehen (Daten 
zwischenspeichern, löschen, schreiben) auf dem Holzweg bin oder ob "man 
das so macht".

Anbei noch ein Bild.

Gruss

von Falk B. (falk)


Angehängte Dateien:

Lesenswert?

@ Holger Krähenbühl (holgerkraehe)

>Diese verwenden ebenfalls FatFS mit einem deutlich grösseren Flash Chip.
>Dieser hat 128Kbit Physikalische Sektoren.

Vorsicht mit der Wortwahl! Ein Sektor ist bei einem Flash was ziemlich 
Großes!
Die kleinste Einheit nach dem Byte ist meist eine Page. Das ist auch 
meist die kleinste Schreibeinheit
Danach kommt der Block mit mehreren Pages.
Und dann der Sektor mit mehreren Blöcken.
Und dann der Flash mit mehreren Sektoren.

Siehe Anhang.

>Laut deren Beschreibung, haben sie nur um den FlashChip verwenden zu
>können, und um die damit verbundenen 128k zwischen zu speichern, ein
>externes Ram angeschlossen.

Nur?

>Das nenne ich mal overkill.
>Soweit würde ich jetzt nicht gehen.

EBEN!

>Im schlimmsten fall, brauche ich dann halt noch 4Kbyte für einen
>Physikalischen Sektor. Dies ist verkraftbar. Evtl. gibt es auch Flash
>Chips mit kleineren Sektoren.

DU brauchst keine 4kBYTE. Waren es nicht vorher immer 4kBit?

Selbst ein 32 Mbit IC wie im Anhang mit 528 Bytes/Page braucht keinen 
Zusatzspeicher, der hat sogar ZWEI Buffer.
D.h. man könnte auch den kleineren 4 Mbit Bruder mit 264 Bytes/Page 
nehmen und mittels der beiden Buffer einen FAT Sektor mit 512 Bytes 
abbilden!
Ohne Zusatzaufwand!

von Michael U. (amiga)


Lesenswert?

Hallo,

was mich etwas verwirrt: wenn ich einen SPI-Flash an einen µC hänge, um 
mehr Speicher haben zu wollen, dann löte ich den i.A. nicht aus, um ihne 
irgendwie an einen PC o.ä. zu stecken und zu lesen oder zu beschreiben.

Damit will ich mir also doch höchstens das Programmierleben leichter 
amchen, weil ein fopen() usw. usw einfacher zu händeln ist, als mit 
Zeigern und Längenangaben, Sektorgrößen usw. bei direktem Zugriff.

Wenn ich das will, hänge ich entweder per SPI eine SD-Card ran, die kann 
ich dann auch im Cardreader bedienen oder nehme ein Filesystem, daß 
wenigstens halbwegs dafür ausgelegt ist.
Deshalb nur kam mein Vorschlag mit dem SPIFFS, die Frage hier ist reines 
Interesse, wenn ich ein Filesystem  ohnehin an meine spezielle Umgebung 
anpassen muß, sollte das merklich weniger Aufwand bedeuten.
Wear-leveled SPI flash file system for embedded devices spricht ja beim 
SPIFFS dafür, daß die meiste Arbeit schon jemand gemacht hat.

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Holger K. (holgerkraehe)


Lesenswert?

Hallo zusammen

Ich möchte der vollständigkeitshalber hier noch auf diesen Thread 
verweisen von mir:

Beitrag "Re: Formatieren mit ElmChan FatFS"

Darin beschreibe ich, wie ich erfolgreich die ursprüngliche 
Problemstellung gelöst habe.

Gruss
Krähe

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.