I'm using a STM32L432 microcontroller to read data from a microSD card via SPI. In my application, I'm playing a sound file with a length of 10 s in loop.
I found out that after the application ran for approximately 20 – 25 hours, the audio stream gets heavily interrupted by noticeable gaps that occur multiple times per second. This can be observed on 10% of all microSD cards that I tested. It occurs for SanDisk, Kingston and all other brands that I tested. Stopping the application and letting the microSD card rest for some days does not solve the problem. It seems that the flash section of the microSD cards that stores the sound file got deteriorated. Reformatting the microSD card fixes it, probably because the sound file gets stored on another flash section.
A further investigation yielded that the gaps in the audio stream occur because the microSD card takes too long to respond to the CMD17 command. When the microSD card is new, the responds take never longer than 4 ms in our tests. However, after a usage of 20 – 25 hours, the respond time increases to up to 95 ms on 10% of all microSD cards.
I'm a bit confused of this result because I did not expect the performance of the microSD cards to deteriorate if only read operations were carried out. Do you have any experience with that? Would the response time decrease when using SDIO instead?
Best Answer
Hm, my usual suspicion would be that your read access goes through a file system and that updates something, e.g. a file access time, in the file system, but that doesn't seem to be the case here.
Next thing I'm guessing: You're experiencing read disturb, a phenomenon where reading the same cell over and over again charges neighboring memory cells ever so slightly every time, or the consequence of the flash controller avoiding it:
You're probably aware that between your SD card interface and the physical isolated gate charges in your NAND flash, there's multiple layers of abstraction:
and, here:
You reading the same cells with CMD17 (which will most certainly be very suboptimal in terms of 3., use CMD18 maybe?) very much sounds either you're corrupting their neighbors (thus leading to increased time in 2.) or leading to copious re-mapping of blocks (in 4.).
I'm a bit surprised: reading audio does sound like a low-throughput operation, compared to, say, reading camera photos, but if your access pattern is very inefficient, say, you read a byte using CMD17; the flash controller has to fetch a full 2048 B block¹, then correct it, throw away all but one byte of the result, give that byte back to the SPI interface, and you then read another byte, which requires the flash controller to read 2048 B, correct.. and so on, you might be doing a very high multiple of the actual read access you think you're doing! That's unfortunate, because audio reading is probably pretty sequential.
So, my recommendation is to write a cleverer SPI SD card interface that fetches long blocks of data, and caches these in MCU RAM. This
¹number taken from random guessing, but order of magnitude would fit the size of error correction block codes I'd expect on modern cheap NAND flash.