SD Card default / high speed

Posts: 9
Joined: Fri Oct 06, 2017 10:27 am

SD Card default / high speed

Postby CharlesSeartech » Thu Nov 30, 2017 1:56 pm


I am currently using the SD card interface on the ESP-WROOM-32 and the read/write speeds are not as expected. I am using a SanDisk 16GB HC Class 2, SanDisk Ultra 32GB HC I Class 10 and a Lexar 1000x HCII Class 10 U3.
At first I was surprised to see that is was using the default speed and not the high speed interface (sdmmc_card_print_info()). Digging in the code I found that max_freq_khz in SDMMC_HOST_DEFAULT() macro was set to use SDMMC_FREQ_DEFAULT and not SDMMC_FREQ_HIGHSPEED. In sdmmc_card_init() a test is done to check if config->max_freq_khz is >= SDMMC_FREQ_HIGHSPEED before sdmmc_enable_hs_mode() is called to test the SD card.
I changed max_freq_khz in SDMMC_HOST_DEFAULT() to SDMMC_FREQ_HIGHSPEED and the SD cards now report that they support high speed mode.

Unfortunately there was not a massive transfer improvement as expected.
Test done transferring 8MB in 2848 byte blocks:
SanDisk 16GB HC C2: 638kB/s to 754kB/s on first block and then 692kB/s, 638kB/s and then subsequent blocks are only 202kB/s.
SanDisk Ultra 32GB HC I C10: 638kB/s to 692kB/s.
Lexar 1000x HCII Class 10 U3: 1384kB/s to 1660kB/s.

1. Can anybody explain why there was not a massive speed improvement using the high speed clock?
2. Why does the transfer on the 16GB card get slower and slower and drop to 202kB/s?

Pseudo code sample:
if (sd_card_init() == ESP_OK)
TickType_t startTick;
TickType_t endTick;
pfile = fopen(fname, "rb");
dataRead = 0;
for(int i=0; i<10; i++)
startTick = xTaskGetTickCount();
for(int i=0; i<2916; i++)
dataRead += fread(ucpData, sizeof(uint8_t), 2848, pfile);
endTick = xTaskGetTickCount();
ESP_LOGW(TAG, "Bytes per sec %dkB/s", dataRead / ((endTick - startTick) / 1000) / 1000);


Posts: 1460
Joined: Tue Dec 01, 2015 8:37 am

Re: SD Card default / high speed

Postby ESP_igrr » Sat Dec 02, 2017 2:09 pm

High SD card read or write throughput can be achieved only when reading or writing large blocks of data at at a time. For example, reading 64kB blocks using sdmmc_read_blocks function, one can get around 17MB/s throughput in HS mode (compared to about 10MB/s in DS mode). When FATFS library is used, read sizes are smaller: in most cases FATFS will read or write one 512-byte block at a time. This is similar to how small TCP window size reduces TCP throughput.

On desktop OSes, SD card or filesystem driver can increase throughput by allocating large intermediate buffer and reading ahead-of-time and/or caching writes (e.g. to perform 1 64kB transfer instead of 128 512-byte transfers). On ESP32, allocating 64kB of RAM "behind the scenes" to increase FATFS read or write performance is not the right tradeoff, for most applications, which is why the driver does not attempt to do that.

There have also been mentions on this forum that SDFat library has better performance than FATFS (on other MCUs). However, until two months ago SDFat was licensed under GPL so we haven't considered integrating it into ESP-IDF.

Posts: 27
Joined: Wed Jan 23, 2019 2:28 pm

Re: SD Card default / high speed

Postby jerome » Mon Mar 11, 2019 10:05 am

I'm facing a similar issue with my SDCArd write speed.
Using high frequency did not help, meaning the problem does not come from the card itself, but from the FATFs implemented in ESP.
Did you find a way to solve that problem ? I need continuous writing without drops while writing.

Who is online

Users browsing this forum: Roudoudoux and 13 guests