Forum: Mikrocontroller und Digitale Elektronik 16 MBit Datenflash mit FAT12 Dateisystem bespielen


von Neb N. (bluemorph)


Lesenswert?

Hallo Community,

ich habe ein Frage an euch und zwar geht es um eine allgemeine 
Problematik zu Filesystem und einem Datenflash.

Folgende Situation:
Datenflash (2 MB) ist über einen parallelen Bus an einen Prozessor 
angebunden. Der Speicher des Datenflashs ist in 64KByte Blöcke 
eingeteilt. Mann kann an alle gerade Adressen schreiben und lesen. 
Löschen kann man allerdings nur einen kompletten 64K-Block. Der 
Prozessor hat einen Arbeitsspeicher von 64K.

Jetzt meine Frage:
Hat einer von euch eine Idee oder Anregung, wie man trotz der 64kByte 
großen Blöcke und des nur 64 kByte großen Arbeitsspeicher vernünftig mit 
einem FAT12 Dateisystem auf dem Datenflash arbeiten kann?

Das Problem besteht ja beim Ändern von Daten, den theoretische muss ich 
dann einen ganzen 64 KByte Block einlesen, irgendwo Speichern, 
Editieren, den betroffenen 64K-Block löschen und den editierten Block 
wieder einfügen. Doch wie macht man das am schlausten mit nur 64kByte 
Arbeitsspeicher?

Ich hoffe ihr habt vielleicht ein paar Tipps für mich!

MfG BlueMorph

von holger (Gast)


Lesenswert?

Welcher Datenflash?

>Doch wie macht man das am schlausten mit nur 64kByte
>Arbeitsspeicher?

Einen Flash mit kleineren Sektoren nehmen.

von Neb N. (bluemorph)


Lesenswert?

Hallo holger,

Danke erstmal für deine Antwort!

> Welcher Datenflash?

Also eigentlich ist es ja egal welcher Datenflash. Es geht ja darum, 
dass dieser Datenflash in 64k-Blöcke eingeteilt ist. Aber weil es dich 
interessiert, es handelt sich um das Flash: ES29LV800D.

> Einen Flash mit kleineren Sektoren nehmen.

Gibt es ein Flash mit kleinerer Sektorgröße im TSOP 48 Gehäuse und mit 
parallelem Bus? Ich bin für jeden Vorschlag offen ...
Im Idealfall müssten die Sektoren ja 512 Bytes groß sein.

von holger (Gast)


Lesenswert?

>Gibt es ein Flash mit kleinerer Sektorgröße im TSOP 48 Gehäuse und mit
>parallelem Bus?

Wüsste ich jetzt auch keinen.
Serielle SPI Flash gibt es mit kleinerer Sektorgröße.
Parallele auch, aber die sind alle < 512kB.

Alternativ RAM aufrüsten wenns geht. Aber das löschen eines
64kB Sektors kostet auch Zeit. Evtl. bist du da mit
einem Serial Flash besser dran.

von Frank K. (fchk)


Lesenswert?

Benny Nestler schrieb:

>> Einen Flash mit kleineren Sektoren nehmen.
>
> Gibt es ein Flash mit kleinerer Sektorgröße im TSOP 48 Gehäuse und mit
> parallelem Bus? Ich bin für jeden Vorschlag offen ...
> Im Idealfall müssten die Sektoren ja 512 Bytes groß sein.

16 Mbit (x8) Multi-Purpose Flash Plus
SST39VF1681 (Bottom Boot) / SST39VF1682 (Top Boot)

hat 4k Sektoren und einen Sector Erase Befehl.

Aber FAT halte ich nicht für optimal für Flash, wegen der Konzentration 
der Schreibzugriffe auf die FAT.

fchk

von holger (Gast)


Lesenswert?

>Aber FAT halte ich nicht für optimal für Flash, wegen der Konzentration
>der Schreibzugriffe auf die FAT.

Kann man mit einem FAT Cache minimieren.
Hat dann aber andere Nachteile falls mal
der Strom ausfällt;)

von Neb N. (bluemorph)


Lesenswert?

Hallo Frank,

> 16 Mbit (x8) Multi-Purpose Flash Plus
> SST39VF1681 (Bottom Boot) / SST39VF1682 (Top Boot)
> hat 4k Sektoren und einen Sector Erase Befehl.

Danke für deine Vorschläge! Die hören sich ja auf jedenfall schonmal gut 
an. Ich denke 4k Arbeitsspeicher könnte ich benutzen um die Sektoren bei 
Bedarf zu puffern.

> Aber FAT halte ich nicht für optimal für Flash, wegen der Konzentration
> der Schreibzugriffe auf die FAT.

FAT ist aber zwingend notwendig, wenn das Datenflash mal über Windows 
gelesen werden soll. Oder gibt es von dir da auch ne gute Idee?

Danke auch dir holger für dein Kommentar bezüglich des FAT Caches. 
Sicherlich muss ich mit FAT Cache arbeiten, da sonst einfach wirklich 
zuviele Zugriffe aufs Flash gemacht werden.

MfG BlueMorph

von Sascha W. (sascha-w)


Lesenswert?

> FAT ist aber zwingend notwendig, wenn das Datenflash mal über Windows
> gelesen werden soll. Oder gibt es von dir da auch ne gute Idee?
wie soll das gelesen werden? Über deinen Prozessor?!
Aber ich glaube das das verwenden von Blockgrößen <>512Byte Problem 
geben wird. -> siehe auch bei neueren (großen) Festplatten.

Kannst du nicht einfach eine SD-Karte nehmen, oder ne CF-Karte wenns 
parallel sein muss.

Sascha

von Neb N. (bluemorph)


Lesenswert?

Hey Sascha,

> wie soll das gelesen werden? Über deinen Prozessor?!

Ja genau das soll dann über den Prozessor gelesen werden, der ist dann 
über USB an den Rechner angeschlossen. CF oder SD Karten kommen nicht in 
Frage.

> Aber ich glaube das das verwenden von Blockgrößen <>512Byte Problem
> geben wird.

Da gebe ich dir recht. Ich denke allerdings das man dieses Problem lösen 
könnte. Die Zugriffsroutinen müssen halt entsprechend ausgelegt werden.

von Frank K. (fchk)


Lesenswert?

Benny Nestler schrieb:
> Hallo Frank,
>
>> 16 Mbit (x8) Multi-Purpose Flash Plus
>> SST39VF1681 (Bottom Boot) / SST39VF1682 (Top Boot)
>> hat 4k Sektoren und einen Sector Erase Befehl.
>
> Danke für deine Vorschläge! Die hören sich ja auf jedenfall schonmal gut
> an. Ich denke 4k Arbeitsspeicher könnte ich benutzen um die Sektoren bei
> Bedarf zu puffern.

Und das Dateisystem so ausrichten, dass die Cluster mit den 
Flash-Sektoren übereinstimmen!

>> Aber FAT halte ich nicht für optimal für Flash, wegen der Konzentration
>> der Schreibzugriffe auf die FAT.
>
> FAT ist aber zwingend notwendig, wenn das Datenflash mal über Windows
> gelesen werden soll. Oder gibt es von dir da auch ne gute Idee?

Wer sagt denn, dass das blockweise geschehen soll? Wenn in Deiner 
Software Dateitransferbefehle eingebaut sind, ist es nach außen gar 
nicht sichtbar, wie die Daten intern abgespeichert werden. Und fürs 
Dateisystem kannst Du im Linux-Kernel nachschauen, wie andere Leute das 
machen (JFFS2 und Konsorten). Und die Lösungen dort sind erprobt.

Wenn Du FAT nehmen willst, dann eher auf einem wechselbaren 
Flash-Speicher (CF, SD). Den kannst Du einfach austauschen, wenn nach 
einem Jahr Fehler auftauchen. Bei einem TSOP48 ist das zwar auch 
möglich, aber nicht ganz so einfach.

fchk

von Joerg W. (joergwolfram)


Lesenswert?

Man braucht nicht zwingend 64 Kilobytes, um bei einer Änderung in einem 
Sektor diesen löschen zu können. Es ist einfacher, einen freien Sektor 
zu löschen, die nicht zu ändernden Daten zu kopieren, die geänderten 
Daten zu schreiben und den bisherigen Saktor als frei zu markieren. Die 
Information, ob ein Sektor frei ist und wie oft er schon beschrieben 
wurde, kann man in den ersten 512 Bytes Block schreiben, die restlichen 
127 sind für die Daten. Für FATxx und ähnliche Dateisysteme ist das aber 
weniger geeignet, das müsste der Controller dannn simulieren.

Jörg

von Neb N. (bluemorph)


Lesenswert?

Hallo Joerg,

danke auch dir für deinen Vorschlag. So wie du es beschreibst, geht es 
natürlich, allerdings lässt sich damit kein FAT Dateisystem realisieren 
(schreibst du ja auch). Im Prinzip ist die Anforderung das man den 
Prozessor per USB an einen PC anschließt und das die Daten aus dem 
Datenflash als Dateien eines Massenspeichers ausgelesen werden können.

Hallo Frank,

>Wer sagt denn, dass das blockweise geschehen soll? Wenn in Deiner
>Software Dateitransferbefehle eingebaut sind, ist es nach außen gar
>nicht sichtbar, wie die Daten intern abgespeichert werden. Und fürs
>Dateisystem kannst Du im Linux-Kernel nachschauen, wie andere Leute das
>machen (JFFS2 und Konsorten). Und die Lösungen dort sind erprobt.

Das verstehe ich irgendwie nicht. Ich würde natürlich gerne ein besser 
geeignetes Dateisystem nehmen, allerdings kann doch Windows nur mit FAT 
und NTFS Dateisystemen umgehen. Und die Anforderung ist quasiu den 
Prozessor per USB anzubinden und das Datenflash als Massenspeicher zu 
initialisieren und dann Dateien darauf abzulegen und zu bearbeiten.

Gruß BlueMorph

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Benny Nestler schrieb:
> CF oder SD Karten kommen nicht in Frage.

Warum?

von Neb N. (bluemorph)


Lesenswert?

Hallo Rufus,

>> CF oder SD Karten kommen nicht in Frage.
>
> Warum?

Weil das für die benötigten Zwecke viel zu oversized wäre. Außerdem ist 
das flash im tsop 48 Gehäuse durch das Layout schon vorgegeben.

Gruß Bluemorph

von holger (Gast)


Lesenswert?

>Das verstehe ich irgendwie nicht. Ich würde natürlich gerne ein besser
>geeignetes Dateisystem nehmen, allerdings kann doch Windows nur mit FAT
>und NTFS Dateisystemen umgehen. Und die Anforderung ist quasiu den
>Prozessor per USB anzubinden und das Datenflash als Massenspeicher zu
>initialisieren und dann Dateien darauf abzulegen und zu bearbeiten.

USB Mass Storage basiert doch irgendwie auf SCSI soweit ich
weiss. Im Endeffekt fragt dich Win nur nach dem Inhalt
von Sektoren. Da könnte man schon ein bißchen schummeln;)

von Frank K. (fchk)


Lesenswert?

Benny Nestler schrieb:


>>Wer sagt denn, dass das blockweise geschehen soll? Wenn in Deiner
>>Software Dateitransferbefehle eingebaut sind, ist es nach außen gar
>>nicht sichtbar, wie die Daten intern abgespeichert werden. Und fürs
>>Dateisystem kannst Du im Linux-Kernel nachschauen, wie andere Leute das
>>machen (JFFS2 und Konsorten). Und die Lösungen dort sind erprobt.
>
> Das verstehe ich irgendwie nicht. Ich würde natürlich gerne ein besser
> geeignetes Dateisystem nehmen, allerdings kann doch Windows nur mit FAT
> und NTFS Dateisystemen umgehen. Und die Anforderung ist quasiu den
> Prozessor per USB anzubinden und das Datenflash als Massenspeicher zu
> initialisieren und dann Dateien darauf abzulegen und zu bearbeiten.

ok, wenn die Anforderung besteht, das Flash als Standard USB Mass 
Storage bereitzustellen, dann geht nur FAT.

Meine Idee war, einfach eine Art FTP-Protokoll einzubauen, so dass der 
Host sagt "put datei1.txt" und eine Datei überträgt und Dein Teil die 
Datei entgegennimmt und irgendwie abspeichert. Dito mit "get datei.txt" 
und "dir". Bei dieser Methode tritt das Flash-Filesystem nicht direkt 
nach außen in Erscheinung.

Du kannst ja auch per ftp übers Netz Dateien von einer Linux-Kiste 
saugen, ohne dass Dein Windows-Rechner das Linux ext3fs oder xfs oder 
btrfs können muss.

Jetzt klarer?

fchk

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Es gibt keine Standardgeräteklasse für derartige Protokolle über USB. 
Sicher ließe sich so etwas basteln, dann aber müsste dafür auch ein 
passender Treiber bzw. eine passende Client-Applikation geschrieben 
werden, was vom Gebrauchswert her doch deutlich unter einem 
USB-Mass-Storage-Device liegt, das man einfach nur anschließen muss, um 
es benutzen zu können, ohne auch nur irgendwelche Software installieren 
zu müssen.

Benny Nestler schrieb:
>> Warum?
>
> Weil das für die benötigten Zwecke viel zu oversized wäre. Außerdem ist
> das flash im tsop 48 Gehäuse durch das Layout schon vorgegeben.

Eine MicroSD-karte nimmt inklusive Sockel nicht mehr Platz weg als 
TSOP-48, allerdings muss sie per SPI angesteuert werden und kann nicht 
an einem parallelen Bus hängen. Dafür ist die Ansteuerung von den 
Dingern schon oft gemacht worden, besonders teuer sind sie auch nicht 
...

Wenn aber das Layout schon fest vorgegeben ist, dann wird die 
Angelegenheit knapp. Da müsstest Du nach einem anderen pinkompatiblen 
Flash-Baustein mit erheblich geringerer Blockgröße suchen.

von Neb N. (bluemorph)


Lesenswert?

Hallo Leute,

ich wollte euch nur ein bisschen berichten, wie ich so vorangekommen 
bin.

Also ich habe auf dem Datenflash nun ein FAT12 Dateisystem 
initialisiert. Den MBR (bzw. PBR), den Windows benötigt habe ich 
statisch aufgesetzt. Damit ist er also nicht Bestandteil des 
Datenflashs.

Im Prinzip sieht das Flash nun wie folgt aus:

/*****************************************
/*    FAT (6 Sektoren à 512 Bytes)       *
/*****************************************
/*    ROOT (26 Sektoren à 512 Bytes)     *
/*****************************************
/*                                       *
/*                                       *
/*    Datenbreich (restliche Sektoren)   *
/*                                       *
/*****************************************

Da ja im Datenflash Werte von 0xFF in 0x00 verändert werden können, 
jedoch nicht von 0 nach 1, musst eich ein paar Konvertierungsroutinen 
schreiben und zusätzlich einige Anpassungen des Dateisystems vornehmen.
Zum Beispiel ist der Initiale Wert eines Bytes (eines Sektors) in 
Windows 0x00. Im Flash wäre das allerdings total schlecht, da ich dann 
keinen Wert einfach so schreiben könnte, ohne vorher den Sektor (man 
bedenke ein Sektor meiens Flashs ist aktuell 64 kBytes groß) zu löschen. 
Der Initiale Wert eines Bytes im Flash ist daher 0xFF.

Immer dann, wenn Windows über USB (SCSI) ein Sektor anfordert läuft 
on-the-fly eine Konvertierungsroutine über den Sektor und mogelt Windows 
einen korrekten Sektor vor. Andersherum ist das dann entsprechend 
genauso.

Im Moment hänge ich jedoch an einer Stelle und zwar stellt es sich als 
Problem dar, wenn Windows eine größere Datei speichert und diese Datei 
in der FAT sektorübergreifend Cluster zugewiesen bekommt.

Ich weis noch nicht so recht, wie ich das Problem lösen kann, vielleicht 
habt ihr ja eine Idee!??

Wenn ich dieses Problem gelöst habe und dann soweit alles klappt, werde 
ich versuchen ein Datenflash mit geringerer Sektorgröße (uniform 
4kBytes) zu ergattern.

MfG BlueMorph

von holger (Gast)


Lesenswert?

>Problem dar, wenn Windows eine größere Datei speichert und diese Datei
>in der FAT sektorübergreifend Cluster zugewiesen bekommt.

Du meinst wenn ein FAT Eintrag über eine Sektorgrenze geht?

>Ich weis noch nicht so recht, wie ich das Problem lösen kann, vielleicht
>habt ihr ja eine Idee!??

Versuch doch mal FAT16. Da kommt das nicht vor.

von Neb N. (bluemorph)


Lesenswert?

Genau, ich meine wenn soviel Cluster von der Datei belegt werden, dass 
eben über eine Sektorengrenze geschrieben werden muss. Bzw. tritt das 
Problem auch dann auf, wenn ich einen Sektor FAT bekomme und die letzten 
Bytes (510, 511), als Teil eines gültigen Clusters benutzt werden 
(sprich die Cluster sind nicht frei, also 000).

Das Problematische dabei ist ja nun meine konvertierungsroutine. Im 
ersten Sektor der FAT sind genau 170 komplette Cluster, die erstrecken 
such von Byte 0 bis 509. Die nächsten beiden Cluster liegen in Byte 510 
und 511 des selben Sektors, das dritte Byte, was ich allerdings benötige 
ist das 0te Byte des nächsten Sektors der FAT und an den komme ich nicht 
so einfach heran.

Sicher bei FAT16 hätte ich das Problem nicht. Macht es allerdings Sinn 
auf einen 1 bzw. 2 MB großes Datenflash ein FAT16 System zum spielen? 
Müsste ich mal durchrechnen. Vielleicht ist das ja auch gar nicht so 
schlimm.

MfG BlueMorph

von Neb N. (bluemorph)


Lesenswert?

holger schrieb:
> Versuch doch mal FAT16. Da kommt das nicht vor.

Hat jemand zufällig noch ne andere Idee???

LG BlueMorph

von Sascha W. (sascha-w)


Lesenswert?

du könnetst die Cluster welche in der FAT, die Sektorgrenze 
überschreiten als belegt markieren - den Eintrag der FAT brauchst du 
aber nicht lesen, da sich das ja in der Software schon vor dem Auslesen 
berechnen lässt.
Verschwendet nur etwas Speicher.

Sascha

von Neb N. (bluemorph)


Lesenswert?

Das ist glaube ich gar nicht so eine schlechte Idee. Insgesamt würde das 
nur 4 kBytes verschwenden. Das ist schonmal wirklich ein guter Ansatz. 
Danke dir für die gute Idee.

MfG BlueMorph

von Frank K. (fchk)


Lesenswert?

Halte die FAT komplett im RAM und schreibe sie nur nach längeren 
Zugriffspausen weg. Wenn Du das RAM mit einer Batterie oder einem 
Goldcap pufferst, um so besser. Das erhöht die Lebensdauer des Flashes 
erheblich. Die Datenbereiche halte ich eigentlich für nicht so kritisch.

Wenn Du mal die von mir empfohlenen 4k-Flashes nimmst, mach die Cluster 
auch gleich 4k groß und sorge dafür, dass die FAT eigene 4k-Sektoren 
hat. Reserviere am Ende der FAT ein DWORD für einen Zähler, den Du bei 
jedem Schreibvorgang hochzählst. Reserviere für die FAT den n-fachen 
Platz, sodass Du die Schreibvorgänge auf n Kopien verteilen kannst, was 
dann auch wieder der Lebensdauer und der Datensicherheit zugute kommt. 
Beim Booten siehst Du dann an Schreibzähler, was die neueste FAT-Kopie 
ist.

fchk

von Max (Gast)


Lesenswert?

Du könntest auch den Ansatz für Wear Leveling von JFFS2 und Konsorten 
einbauen. Jedes Sektor bekommt einen Header verpasst (so 6-8 Bytes) in 
denen du dessen Status speicherst. ZB so:
1
struct {
2
  uint8_t flags; // Bit-flags für verwendet, obsolute, schreibfehler, etc
3
  uint16_t id; // Welcher Sektor wir eigentlich sind
4
  uint16_t crc; // damit wir wissen dass hier alles ok ist
5
  uint8_t data[512]; // die daten halt
6
}

Dadurch dass man Flash von 1 --> 0 schreiben kann, können die Flags 
aktuallisiert werden ohne dass man den Sektor löschen muss. Wenn nun ein 
Sektor geschrieben wird, so schreibst man die Flags und kopiert den 
neuen Inhalt in einen leeren Speicherbereich. Sind alle Blöcke in einem 
Erase Block auf obsolute gesetzt, so löscht man diesen.

Nachteil von dem ist natürlich, dass man den gesamten Flash nach einem 
Sektor durchsuchen muss. Schnell wird's sicher nicht. Wenn du was 
schnelles willst, wird eine Baumstruktur, wie bei JFFS2 am Besten sein. 
Den Quellcode kannst du dir zB bei eCos angucken.

Auf diesen kann man dann das FAT dann aufsetzten, wie gut das gehen 
wird, ka, hab ich noch nie gemacht :D.

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.