Forum: Mikrocontroller und Digitale Elektronik Was ist die Block-Größe meines SPI-ROMs auf dem ESP8266?


von A. S. (rava)


Angehängte Dateien:

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?

: Bearbeitet durch User
von Stephan S. (uxdx)


Angehängte Dateien:

Lesenswert?

A. S. schrieb:
> Leider sehe ich bei meinem Wemos nicht, welcher chip da verbaut ist.

Evtl das hier

Beitrag #7671407 wurde vom Autor gelöscht.
von Klaus H. (klummel69)


Lesenswert?

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

von A. S. (rava)


Angehängte Dateien:

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

von Gerald B. (gerald_b)


Lesenswert?

Auf dem SO8 Gehäuse steht 25V032, also maximale Ausbaustufe 32 MB

von Stephan S. (uxdx)


Lesenswert?

das sieht ganz interessant aus: 
https://www.esp8266.com/viewtopic.php?p=31791

von Klaus H. (klummel69)


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

von Stephan S. (uxdx)


Lesenswert?

Klaus H. schrieb:
> Der Link geht ins Leere, man findet die Datei aber auf dem Server.

Hier ein Link 
https://chromium.googlesource.com/external/coreboot.org/flashrom/+/refs/heads/staging/flashchips.h

von A. S. (rava)


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 );

: Bearbeitet durch User
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.