In SDIO four wire mode, the file reading speed is very slow and the writing speed is normal
Posted: Sun Apr 17, 2022 7:37 am
The hardware I use is esp32 S3
The IDF version is 4.4
When using SDIO, I encountered the problem of slow file reading speed
What I expect is that the speed of reading files is fast, and the speed of writing files is not important
The IDF version is 4.4
When using SDIO, I encountered the problem of slow file reading speed
What I expect is that the speed of reading files is fast, and the speed of writing files is not important
Code: Select all
esp_err_t ret;
// Options for mounting the filesystem.
// If format_if_mount_failed is set to true, SD card will be partitioned and
// formatted in case when mounting fails.
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
#ifdef CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED
.format_if_mount_failed = true,
#else
.format_if_mount_failed = false,
#endif // EXAMPLE_FORMAT_IF_MOUNT_FAILED
.max_files = 5,
.allocation_unit_size = 16 * 1024
};
// sdmmc_card_t *card;
// const char mount_point[] = SD_MOUNT_POINT;
// ESP_LOGI(TAG, "Initializing SD card");
// Use settings defined above to initialize SD card and mount FAT filesystem.
// Note: esp_vfs_fat_sdmmc/sdspi_mount is all-in-one convenience functions.
// Please check its source code and implement error recovery when developing
// production applications.
ESP_LOGI(TAG, "Using SDMMC peripheral");
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
host.max_freq_khz = SDMMC_FREQ_HIGHSPEED;
// This initializes the slot without card detect (CD) and write protect (WP) signals.
// Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
// To use 1-line SD mode, change this to 1:
slot_config.width = 1;
// On chips where the GPIOs used for SD card can be configured, set them in
// the slot_config structure:
#ifdef SOC_SDMMC_USE_GPIO_MATRIX
slot_config.clk = GPIO_NUM_14;
slot_config.cmd = GPIO_NUM_15;
slot_config.d0 = GPIO_NUM_2;
slot_config.d1 = GPIO_NUM_4;
slot_config.d2 = GPIO_NUM_12;
slot_config.d3 = GPIO_NUM_13;
#endif
// Enable internal pullups on enabled pins. The internal pullups
// are insufficient however, please make sure 10k external pullups are
// connected on the bus. This is for debug / example purpose only.
slot_config.flags |= SDMMC_SLOT_FLAG_INTERNAL_PULLUP;
ESP_LOGI(TAG, "Mounting filesystem");
ret = esp_vfs_fat_sdmmc_mount(mount_point, &host, &slot_config, &mount_config, &card);
if (ret != ESP_OK) {
if (ret == ESP_FAIL) {
ESP_LOGE(TAG, "Failed to mount filesystem. "
"If you want the card to be formatted, set the EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option.");
} else {
ESP_LOGE(TAG, "Failed to initialize the card (%s). "
"Make sure SD card lines have pull-up resistors in place.", esp_err_to_name(ret));
}
return;
}
ESP_LOGI(TAG, "Filesystem mounted");
// Card has been initialized, print its properties
sdmmc_card_print_info(stdout, card);
// Use POSIX and C standard library functions to work with files:
Code: Select all
#define TEST_FILE_SIZE (4 * 1024 * 1024)
static void testWriteFile(const char *path, uint8_t *buf, int len)
{
unsigned long start_time = esp_timer_get_time()/1000;
ESP_LOGI(TAG, "Test write %s", path);
FILE *fd = fopen(path, "wb");
if (!fd)
{
ESP_LOGI( TAG, "Failed to open file for writing" );
return;
}
int loop = TEST_FILE_SIZE / len;
while (loop--)
{
if (fwrite(buf, 1, len, fd) <= 0)
{
ESP_LOGI( TAG, "Write failed" );
return;
}
}
fclose( fd );
unsigned long time_used = esp_timer_get_time()/1000 - start_time;
cmd_printf( "Write file used: %ld ms, %f KB/s\r\n", time_used, (float)TEST_FILE_SIZE / time_used);
}
static void testReadFile(const char *path, uint8_t *buf, int len)
{
unsigned long start_time = esp_timer_get_time()/1000;
ESP_LOGI( TAG, "Test read %s", path );
FILE *fd = fopen(path, "rb");
if (!fd)
{
ESP_LOGI( TAG, "Failed to open file for reading" );
return;
}
int loop = TEST_FILE_SIZE / len;
while (loop--)
{
if (fread(buf, 1, len, fd) <= 0)
{
ESP_LOGI( TAG, "Read failed" );
return;
}
}
fclose( fd );
unsigned long time_used = esp_timer_get_time()/1000 - start_time;
cmd_printf( "Read file used: %ld ms, %f KB/s\r\n", time_used, (float)TEST_FILE_SIZE / time_used );
}
static int sdcard_speed_test_cmd(int argc, char **argv)//SD卡测试代码
{
/* malloc will not reset all bytes to zero, so it is a random data */
// uint8_t *buf = (uint8_t*)malloc(64 * 1024);
uint8_t *buf = (uint8_t*)malloc_ram(64 * 1024);
testWriteFile(SD_MOUNT_POINT"/test_1k.bin", buf, 1024);
testReadFile(SD_MOUNT_POINT"/test_1k.bin", buf, 1024);
// unlink(SD_MOUNT_POINT"/test_1k.bin");
testWriteFile(SD_MOUNT_POINT"/test_2k.bin", buf, 2 * 1024);
testReadFile(SD_MOUNT_POINT"/test_2k.bin", buf, 2 * 1024);
// unlink(SD_MOUNT_POINT"/test_2k.bin");
testWriteFile(SD_MOUNT_POINT"/test_4k.bin", buf, 4 * 1024);
testReadFile(SD_MOUNT_POINT"/test_4k.bin", buf, 4 * 1024);
// unlink(SD_MOUNT_POINT"/test_4k.bin");
testWriteFile(SD_MOUNT_POINT"/test_8k.bin", buf, 8 * 1024);
testReadFile(SD_MOUNT_POINT"/test_8k.bin", buf, 8 * 1024);
// unlink(SD_MOUNT_POINT"/test_8k.bin");
testWriteFile(SD_MOUNT_POINT"/test_16k.bin", buf, 16 * 1024);
testReadFile(SD_MOUNT_POINT"/test_16k.bin", buf, 16 * 1024);
// unlink(SD_MOUNT_POINT"/test_16k.bin");
testWriteFile(SD_MOUNT_POINT"/test_32k.bin", buf, 32 * 1024);
testReadFile(SD_MOUNT_POINT"/test_32k.bin", buf, 32 * 1024);
// unlink(SD_MOUNT_POINT"/test_32k.bin");
testWriteFile(SD_MOUNT_POINT"/test_64k.bin", buf, 64 * 1024);
testReadFile(SD_MOUNT_POINT"/test_64k.bin", buf, 64 * 1024);
// unlink(SD_MOUNT_POINT"/test_64k.bin");
free(buf);
return 0;
}