Hallo,
ich habe einen STM32 mit ext. NAND-Flash. Hier kann ich über die
HAL-Funktionen von ST lesend und schreibend zugreifen (jeweils 2kB)
sowie löschen (64x2kB). Nun habe ich littleFS eingebunden um mir die
Datenverwaltung auf dem Flash einfacher zu machen. Das hat soweit auch
super funktioniert und das Beispiel welches dabei ist mit dem
Boot-Counter hat funktioniert.
Nun möchte ich viele Dateien mit jeweils wenig Inhalt anlegen (ca. 800,
meistens nur 1-12 Byte). Nachdem aber ca. 20 angelegt wurden dauert das
Erstellen einer Datei ab und zu (das schließen, denn da wird erst auf
das Flash geschrieben) sehr lange. Hier liest littleFS ein paar sektoren
vielfach aus und nach der Zeit hat das ganze aber auch erfolgreich
funktioniert. Obwohl die Dateigröße jeweils fast gleich ist passiert das
nur ab und zu. Teils sind es 6000 Lesezugriffe auf die selbe Page.
Meine littleFS-Konfiguration sieht so aus:
1
conststructlfs_configcfg={
2
// block device operations
3
.read=Hal_Memory_LFS_Block_Read,
4
.prog=Hal_Memory_LFS_Block_Prog,
5
.erase=Hal_Memory_LFS_Block_Erase,
6
.sync=Hal_Memory_LFS_Block_Sync,
7
8
// block device configuration
9
.read_size=2048,// page read is 2048 bytes
10
.prog_size=2048,// page program is 2048 bytes
11
.block_size=131072,// 64 pages per block -> 64 * 2048 bytes
Bei dem github-Repo von littleFS sind ein paar Issues die in eine
ähnliche Richtung gehen, aber weder eine Erklärung noch ein
Lösungsansatz.
Hat jemand von euch littleFS erfolgreich im Einsatz? Aktuell habe ich
keinen Ansatz den ich verfolgen kann.
Viele Grüße,
ch
ch schrieb:> Nun möchte ich viele Dateien mit jeweils wenig Inhalt anlegen (ca. 800,> meistens nur 1-12 Byte). Nachdem aber ca. 20 angelegt wurden dauert das> Erstellen einer Datei ab und zu (das schließen, denn da wird erst auf> das Flash geschrieben) sehr lange. Hier liest littleFS ein paar sektoren> vielfach aus und nach der Zeit hat das ganze aber auch erfolgreich> funktioniert. Obwohl die Dateigröße jeweils fast gleich ist passiert das> nur ab und zu. Teils sind es 6000 Lesezugriffe auf die selbe Page.
Ich habe den Code von LittleFS nicht analysiert, aber selber mal sowas
Ähnliches geschrieben. Und wenn ich das in Systemen einsetze, bei denen
der RAM sehr beschränkt ist, dann passiert genau dasselbe.
Das Problem ist dabei einfach, dass letztlich eine hierarchische
Verwaltungsstruktur umgesetzt werden muss und die Blockgröße der
Varwaltungsinformationen natürlich der Blockgröße des Targets
entspricht. Reicht nun der RAM nicht, um wenigstens 2..3 Blöcke zu
cachen, führt das unweigerlich dazu, dass bei der Erstellung der
nächsten "Generation" die Daten des alten Rootblocks immer und immer
wieder eingelesen werden müssen, weil der zwischenzeitlich aus dem Cache
geflogen ist. Bei Nodes in tieferen Schichten der Hierarchie passiert
das genauso, nur schon sehr viel seltener und fällt deswegen nicht so
auf.
Also: einzige Abhilfe ist ein größerer Cache im RAM. Wenn du Glück hast,
hast du erstens genug RAM um den zu realisieren und zweitens bietet
dieses LittleFS eine Konfigurationsoption, um den als Cache nutzbar zu
machen.
Mein FS kann das jedenfalls ;o) Meine Targets haben aber leider oft
nicht genug RAM, so dass ich diese Fähigkeit oft nicht nutzen kann. :o(
Hallo,
Danke für deine Antwort. RAM hab ich genügend, da schaue ich mal ob ich
noch was rausholen kann.
Sind hier keine littleFS-Nutzer unterwegs?
Viele Grüße
Ich habe LittleFS testweise zusätzlich zum FAT in einem HTTP Server mit
STM32F407, aber da bisher nur 33 Dateien drin und da macht es keine
Probleme. Es ist die Mbed Komponente, aber die benutzt ja den gleichen
Code, ist aus dem gleichen Haus.
Damit kann man aber schnell einen Test bauen, ich habe gerade einen F411
mit 128 MBit Flash angeklemmt. Das würde das Problem vermutlich nur
bestätigen.
Es gibt auch schon ein LittleFS2, das habe ich aber noch nicht benutzt
und kann nicht sagen was da verbessert/geändert wurde. Das liegt auch
als Branch in dem Repo.
Hallo,
das ist interessant. Bei mir passiert alle 32 Dateien etwas was
hunderte/tausende Lesezugriffe auf die selben paar Pages braucht.
Ich habe jetzt mal alle Caches stark erhöht und es geht wohl jetzt auch
ein wenig schneller (nicht gemessen). Das Problem löst es aber trotzdem
nicht...
Viele Grüße,
Ich habe das mal auf dem F411 laufen lassen, ein kleines Testprogramm
mit Mbed-os 6.1.0 das 1000 Dateien á 12 Byte schreibt.
Mit LFS gehen die Zeiten recht linear hoch, wird dann schneller um
wieder linear anzusteigen.
Da LFSv2 auch schon implementiert ist und nur eine Zeile geändert werden
muss, habe ich das auch laufen lassen. Erstmal ist es für wenige Dateien
deutlich schneller, aber dann hauen heftige zyklische Bedenkzeiten von
13-14 s rein. Das sieht nicht sauber aus, oder LfsV2 macht da
irgendwelche Umstrukturierungen?
Für die Buffer habe ich die defaults belassen.
Beim LfsV2 sind lookahead=64 und cache=64.
Beim LfsV1 sind lookahead=512 und readsize=64, cache sehe ich da nicht.
SPI Clock sollte 40 MHz sein, habe ich nicht nachgemessen. Und es ist
ein Debugbuild, also ohne Optimierung. Aber für den Vergleich sollte das
reichen, und jetzt könnte man noch mit den Cachewerten spielen. Wenn man
in LfsV2 die Spitzen wegbekommt wäre es ja gut...
Hallo,
danke für den Test. Bei mir schaut es ähnlich aus, hab aber die Zeiten
nicht rausgemessen.
Prinzipiell ist das selbe auch hier beschrieben:
https://github.com/ARMmbed/littlefs/issues/203
Ich hab die Caches mal testweise auf 16kB erhöht - es ändert sich
prinzipiell nicht.
Viele Grüße
man sollte einen µC wohl einfach nicht mit sovielen Dateien quälen :)
Bei einer so einer Anfoderung macht es wohl mehr Sinn direkt die Daten
in eigene Blöcke zu packen oder sowas wie Key-Value Storage zu benutzen.
Johannes S. schrieb:> man sollte einen µC wohl einfach nicht mit sovielen Dateien quälen :)
Da ist was dran. Für sehr, sehr viele Anwendungen braucht man nicht
wirklich ein Dateisystem, wenn man nur mal richtig über die eigentliche
Aufgabe nachdenkt.
> Bei einer so einer Anfoderung macht es wohl mehr Sinn direkt die Daten> in eigene Blöcke zu packen
Das ist bei potentiell unzuverlässigem Speicher aber nur höchstens die
halbe Einsparung. Du sparst damit nur die Filesystemstruktur ein (auf
Kosten des Speicherbedarfs). Du sparst aber nicht den Layer ein, der die
Block-Usage verwaltet. Naja, jedenfalls wenn du klug bist, tust du das
nicht...
> oder sowas wie Key-Value Storage zu benutzen.
Das ist nun wirklich völlige Grütze. Oder ich habe die Idee hinter der
Idee nicht verstanden. Inwiefern kann Key-Value-Storage die Probleme
durch unzuverlässigen Flas-Speicher lösen? Magst du das Rätsel auflösen?
c-hater schrieb:> Inwiefern kann Key-Value-Storage die Probleme> durch unzuverlässigen Flas-Speicher lösen?
bei 800 Dateien * 12 Byte, mal aufgerundet auf 1024 * 16 Byte wären 16
kB die noch in den Speicher passen sollten. Diese 16 kB dann in einer
Datei zyklisch sichern, so langsam wie nötig. Dann kann LFS effizienter
arbeiten, braucht viel weniger Verwaltung und kann auch sein wear
levelling einbringen. Setzt natürlich vorraus das sich die Daten nicht
im Sekundentakt ändern. Oder die Daten so organisieren das nicht soviel
aufeinmal geschrieben werden muss.
Das hängt aber doch alles von der Anwendung ab, nur 1000 kleine Dateien
sind sicher keine gute Lösung. Das war aber auch schon mit FAT auf PCs
früher schon so.
Der Test war für mich auch nur um sehen ob es geht und was passiert
wenn. LFS V2 scheint jedenfalls auch besser zu sein. Ich habe den Test
mit Mbed-os nochmal ohne den RTOS Teil gemacht, da kamen Faktor 2
schnellere Zeiten bei raus obwohl der erste Test auch nur als single
thread lief.