Page 1 of 1

SD Card default / high speed

Posted: Thu Nov 30, 2017 1:56 pm
by CharlesSeartech
Hi,

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);
}
fclose(pfile);
}

Regards,
Charles

Re: SD Card default / high speed

Posted: Sat Dec 02, 2017 2:09 pm
by ESP_igrr
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.

Re: SD Card default / high speed

Posted: Mon Mar 11, 2019 10:05 am
by jerome
Hi
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.
Thanks
Jerome

Re: SD Card default / high speed

Posted: Wed Dec 13, 2023 9:18 am
by CyprienAmigon
I'm also facing the same problem. I'm using a fatfs_stream element of ESP-ADF to write audio data in SDCard but the writing speed is not fast enough and I'm lossing data. I've tried with lastest ESP-IDF/ESP-ADF version and it dit not change anything. Any new on this issue ? I'm quite stuck...