Was ist die Block-Größe meines SPI-ROMs auf dem ESP8266?

OP #7671387
Lesenswert?

Für ein privates Sensorprojekt habe ich über einige Jahre hinweg viele log-Daten zu speichern und möchte dabei möglichst wenig "wear" auf meinem flash-ROM verursachen. Daher habe ich mich entschieden, bei meinem ESP8266 Arduino-Projekt auf fertige Dateisysteme zu verzichten und die Daten direkt im Binärformat auf die sonst ungenutzte FS Partition zu schreiben. Diese liegt in dem seriell angebundenen SPI-Flash-ROM des Gerätes.

Gestern habe ich mich mal an einem Konzept versucht und es sieht prinzipell gut aus. Ich werde Daten nur blockweise manipulieren, und möchte die Funktionalität aus "flash_hal.h" (https://github.com/esp8266/Arduino/blob/master/cores/esp8266/flash_hal.h) recyclen, z.B. so:

1
uint32_t _block_to_addr(uint32_t block_nr) {
2
  return block_nr * flash_block_size_bytes + FS_PHYS_ADDR;
3
}
4
bool _read_block(uint32_t block_nr, uint8_t* buf_8192_bytes) {
5
  return flash_hal_read(_block_to_addr(block_nr), flash_block_size_bytes, buf_8192_bytes) == FLASH_HAL_OK;
6
}

Wenn ich also aus dem 4MB Flash ca. 3MB für die FS Partition vergebe, komme ich auf ca. 380 mögliche Blöcke à 8192 Bytes. Ein entsprechender 8kB-Buffer würde schon ganz gut in dem RAM passen und nach meinem Konzept ist auch die Geschwindigkeit spürbar besser, wenn der ganze FS overhead wegfällt.

Jetzt stellt sich mir aber noch die Frage, ob flash_block_size_bytes=8192 Bytes die korrekte physikalische Blockgröße widergibt, denn nur so hält der Speicher ausfallfrei möglichst lange. Der Wert kommt einerseits aus der flash_hal.h weil er so im define FS_PHYS_BLOCK hinterlegt ist; und er taucht auch bei der Kompilierung als FS_BLOCK 0x2000 in der Datei "local.eagle.flash.ld" wieder auf. Ich hänge die mal an...

Trotzdem bin ich nicht 100% sicher, ob da nicht schon eine logische Abstraktionsebene dazwischen hängt und die wahre SPI flash Blockgröße doch eine andere ist. Vielleicht klappen auch meine writes gar nicht komplett wenn ich für diese API eine zu große size wähle? Das konnte ich noch nicht debuggen.

Es jedenfalls ist leider so, dass es im Netz die verbreitete Info gibt, dass SPI Flash Chips eine Standard-Blocksize von 4kB/32kB/64kB haben, siehe z.B. https://github.com/pellepl/spiffs/wiki/Configure-spiffs#configuration-example https://esp32.com/viewtopic.php?t=12896 https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/spiffs.html

Leider sehe ich bei meinem Wemos nicht, welcher chip da verbaut ist.

Die Frage also: gibt es einen noch besseren Weg, um ohne externe Hardware ca. 2MB-3MB Daten zu loggen, als sie blockweise und ohne Dateisystem in den SPI-Flash zu schreiben? Ist die API von "flash_hal.h" dafür sinnvoll? Und gibt es eine bessere Blockgröße als die 8192 Bytes aus der besagten Datei, wenn ich vor allem die Belastung des ROMs über die Jahre klein halten möchte?

Angehängte Dateien:
Beitrag #7671407 wurde von einem Moderator gelöscht.
OP #7671424
Lesenswert?

Stephan S. schrieb:

Evtl das hier

https://www.lcsc.com/product-detail/NOR-FLASH_Zbit-Semi-ZB25VQ32BTIG_C495743.html

In dem Fall wären Sektor 4kB und Block 32kB. Mein ESP allerdings hat stattdessen eine silberne box. Reinschauen ist nicht. sieht aus wie oben auf dieser Seite: https://wolles-elektronikkiste.de/wemos-d1-mini-boards

Klaus H. schrieb:

Das müsste mit dem esptool von espressif auslesbar sein, siehe https://docs.espressif.com/projects/esptool/en/latest/esp8266/index.html

siehe Anhang. Kannst damit was anfangen?

Manufacturer: 5e Device: 4016

Angehängte Dateien:
#7671473
Lesenswert?

Siehe https://nodemcu.readthedocs.io/en/1.5.4.1-final/flash/#determine-flash-size:

The chip ID can then be looked up in https://code.coreboot.org/p/flashrom/source/tree/HEAD/trunk/flashchips.h. This leads to a manufacturer name and a chip model name/number e.g. AMIC_A25LQ032. That information can then be fed into your favorite search engine to find chip descriptions and data sheets.

Der Link geht ins Leere, man findet die Datei aber auf dem Server.

#define TENX_ID_NOPREFIX 0x5E

scheint "Tenx Technologies" zu sein. Der hat aber so wie es scheint keine Flash Speicher im Programm… Mmmm

OP #7671525
Lesenswert?

Ich habe noch ein bisschen herumprobiert und das interface funktioniert jedenfalls auch mit kleineren Blockgrößen. Gegen flash_block_size_bytes = 4096 spricht also auch nichts. Es gehen keine Daten verloren.

Allerdings mit flash_block_size_bytes = 2048 führt der ganze code direkt zum crash und Neustart des ESP.

Das wäre schonmal ein Hinweis auf 4kB Blockgröße.

1
17:54:34.259 -> _spif_erase called with addr=100800, size=2048
2
17:54:34.259 -> 
3
17:54:34.259 -> User exception (panic/abort/assert)
4
17:54:34.259 -> --------------- CUT HERE FOR EXCEPTION DECODER ---------------
5
...
6
17:54:34.324 -> --------------- CUT HERE FOR EXCEPTION DECODER ---------------
7
17:54:34.324 -> 
8
17:54:34.324 ->  ets Jan  8 2013,rst cause:2, boot mode:(3,0)

Dazu kommt dass zwei defines aufgetaucht sind

1
  Serial.println(SPI_FLASH_SEC_SIZE);
2
  Serial.println(FLASH_SECTOR_SIZE);

Beide stehen auf 4096.

Siehe auch: https://github.com/esp8266/Arduino/blob/master/cores/esp8266/flash_hal.cpp#L57

Dann würde ich meine Daten also in 4kB Blöcken in den Flash loggen und glauben dass die 8kB vom SPIFFS als logische Blockgröße definiert wurden.

Bleibt die Frage, warum im ld file steht

1
PROVIDE ( _FS_block = 0x2000 );

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