adafruit / Adafruit_SPIFlash

Arduino library for external (Q)SPI flash device
MIT License
161 stars 86 forks source link

Writing to FLASH-memory intermittently slow: typical 150us vs occasional 65ms #140

Closed tipo1000 closed 10 months ago

tipo1000 commented 1 year ago

Operating System

Windows 10

IDE version

Arduino 1.8.13

Board

Standard Adafruit Itsybitsy M0 express (SAMD21)

BSP version

"Adafruit SAMD Boards" by Adafruit version 1.7.10

SPIFlash Library version

3.11.0

Sketch as attached file if not stock example

Adafruit_SPIFlash_memory_writing_test_2.ino.txt

What happened ?

Writing data to FLASH-memory takes most of the time around 150us. About every 100th write-operation takes around 65ms. This intermittent delay makes the library unsuitable for time critical storage, for example for storing acceleration data continuously.

What can be done to keep write-delay as short as possible?

The write time to FLASH should stay constantly under 1000us in order to be able to log acceleration data with targeted 1000Hz sampling rate.

In my mind the FLASH-chip itself shouldn't be the bottle neck. The datasheet (page 65/79) mentions that "Page Program Time" is typically 0.4ms (max 3ms). https://www.mouser.fi/datasheet/2/949/w25q64jv_revj_03272018_plus-1489671.pdf. This data sheet is not for FLASH-chip on ItsyBitsy board because I can't find information about what FLASH chip Adafruit has assembled.

Attached is a test sketch which is partly based on "Adafruit SPIFlash" -library examples and partly mimics how accelerometer data would be stored to FLASH-memory.

How to reproduce ?

Run the attached sketch.

Debug Log as attached txt file

Output for github error 2.txt

Screenshots

No response

hathach commented 10 months ago

late response, but I think it is due to the cached write. The huge delay is due to the flash erase + write time. When writing to an new dirty flash sector, the sector must be erased before programmed. Fatfs isn't ideal for loging since it will constantly update and rewrite to existing sector (e.g FAT table). If constant-time is your target, you can try to use the SPIFlashBase class without cached and also using the raw API to read/write without using fatfs.