ESP8266 SPIFFS lazy delete möglich

OP #7666870
Lesenswert?

ich baue gerade einen ESP8266 Datenlogger auf Basis des SPIFFS.

Eine Messung meines Sensors

1
struct Measurement {
2
  time_t timestamp;
3
  float temperature_celsius;
4
  float humidity_percent;
5
};

benötigt 16 Bytes.

512 dieser structs werden in einem array im RAM akkumuliert.

1
Measurement measurements_in_ram[NUM_MEASUREMENTS_IN_RAM];

Sobald das array voll ist, wird es in einer von 250 verschiedenen files im SPIFFS auf dem internen flash ROM abgelegt - das geschieht ca. alle 100-200min einmal. Anschließend können die nächsten Messungen im RAM aufgezeichnet werden können.

Gerade beschäftige ich mich aber mit dem Löschen dieser Dateien: Irgendwann möchte ich die Daten abholen und die ROM log komplett löschen.

Mein Ansatz ist, das "lazy" zu erledigen: ein Measurement gilt als leer, wenn die timestamp

1
#define TIME_EMPTY (reinterpret_cast<time_t>(0LL))

abgelegt ist. Wenn also das erste Measurement einer SPIFFS-Datei diese timestamp enthält, ist der ganze Bereich frei und kann später komplett mit 512 neuen Messungen überschrieben werden.

Hier ist mein code für lazy delete:

1
void clear_rom() {
2
  Measurement data = Measurement{ TIME_EMPTY, 0.0, 0.0 };
3
  for (int file_idx = 0; file_idx < NUM_FILES_IN_SPIFFS; ++file_idx) {
4
    File f = SPIFFS.open(fnames[file_idx], "w");
5
    if (!f) {
6
      continue;
7
    }
8
    f.write(reinterpret_cast<uint8_t*>(&data), sizeof(Measurement));
9
    f.close();
10
  }
11
}

obwohl jede Datei NUM_MEASUREMENTS_IN_RAM * sizeof(Measurement) bytes groß ist schreibe ich also nur die ersten 16 Bytes - das geht deutlich schneller als eine Komplettformatierung.

Interessanterweise klappt das genau bei der ersten der 250 Dateien. Alle weiteren bleiben komplett unverändert - auch im ersten Measurement. Es ist als würde er irgendwo aus dem loop fliegen.

TLDR

Nun also meine Frage: ich habe 250 SPIFFS Dateien mit je einer Größe von 8kB. Wenn ich nun einige dieser Dateien öffne und jeweils 16 Bytes hineinschreibe und wieder schließe, hat das Auswirkungen auf die Struktur des Dateisystems? Verschieben sich beispielsweise die Addressen der nachfolgenden Dateien unerwartet oder habe ich in irgendeiner anderen Weise UB?

OP #7667353
Lesenswert?

Okay. Ich kann die Antwort selbst geben:

Dateien können teilweise geschrieben werden. Ohne garbage collection oder anderen Maßnahmen zur Defragmentierung ändert das auch nicht den Speicherbereich, der durch die Dateien belegt ist.

In meinem Fall hat sich mal wieder die Arduino IDE umgestellt und den Platz für das Dateisystem reduziert. Passiert bei fast jedem Update. Irgendwann werde ich mich daran gewöhnen...

Gast #7667435
Lesenswert?

A. S. schrieb:

In meinem Fall hat sich mal wieder die Arduino IDE umgestellt

Nimm vscode mit dem Arduino Plugin von Microsoft. Da ha jedes Projekt seine eigene Konfigurationsdatei, wo all diese Einstellungen persistiert werden.

Zum SPIFFS: Mir scheint das Dateisystem unnötig kompliziert für deinen Anwendungsfall. Greife doch einfach direkt auf den Flash Speicher zu.

OP #7667438
Lesenswert?

Danke,

das mit dem Dateisystem ist tatsächlich ein Thema, das ich noch auf dem Zettel habe. Es stört mich schon seit Längerem, dass ich nicht weiß, wie viele fstats und metadaten da im Hintergrund noch meinen wertvollen Flash-Speicher über die Jahre belasten.

Am Ende des Tages will ich ja wirklich nur structs an feste Speicheradressen ablegen. Aber ich brauche halt >2MB von den 4MB Flash und suche daher auch nach einer Lösung, mit der ich sicher sein kann, dass nichts anderes in diesen Bereich schreibt - auch keine OTA Updates oder ähnliche Libs, die da mehr oder weniger heimlich mitspielen wollen.

Hast du zufällig Beispiele oder einen link zu einer Docu, wo ich mir das low-level-Thema mal draufschaffen könnte?

Gast #7667441
Lesenswert?

A. S. schrieb:

suche daher auch nach einer Lösung, mit der ich sicher sein kann, dass nichts anderes in diesen Bereich schreibt

Du könntest den Bereich wie gehabt für SPIFFS reservieren aber dann am SPIFFS vorbei mit eigenem Code benutzen.

Alternativ kenne ich von SD Karten die Variante, das ganze Filesystem mit einer einzigen Dummy Datei voll zu machen, und danach am Filesystem vorbei auf die Speicherblöcke zuzugreifen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren