In SDIO four wire mode, the file reading speed is very slow and the writing speed is normal

Jinsc_esp32
Posts: 7
Joined: Sun Apr 17, 2022 7:16 am

In SDIO four wire mode, the file reading speed is very slow and the writing speed is normal

Postby Jinsc_esp32 » 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
F@`RO7I8E{T1KMAK)H23LRA.jpg
F@`RO7I8E{T1KMAK)H23LRA.jpg (54.99 KiB) Viewed 3349 times

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;
}
F@`RO7I8E{T1KMAK)H23LRA.jpg
F@`RO7I8E{T1KMAK)H23LRA.jpg (54.99 KiB) Viewed 3349 times

rpiloverbd
Posts: 101
Joined: Tue Mar 22, 2022 5:23 am

Re: In SDIO four wire mode, the file reading speed is very slow and the writing speed is normal

Postby rpiloverbd » Sun Apr 17, 2022 1:29 pm

Hi, is the reading speed always the same no matter how big or small the file is?

Jinsc_esp32
Posts: 7
Joined: Sun Apr 17, 2022 7:16 am

Re: In SDIO four wire mode, the file reading speed is very slow and the writing speed is normal

Postby Jinsc_esp32 » Mon Apr 18, 2022 1:38 am

VeryCapture_20220418093426.jpg
VeryCapture_20220418093426.jpg (110.15 KiB) Viewed 3282 times
The file read is the file written earlier
The file size is consistent, but the cache used in reading is 1K ~ 64K respectively

ESP_igrr
Posts: 2072
Joined: Tue Dec 01, 2015 8:37 am

Re: In SDIO four wire mode, the file reading speed is very slow and the writing speed is normal

Postby ESP_igrr » Mon Apr 18, 2022 7:42 am

You can increase read speed by bypassing the file stream buffering.

Please try replacing fread call with read(fileno(fd), buf, len);

(However, if you use 'read', take care not to use 'fread' with the same file stream as well)

Jinsc_esp32
Posts: 7
Joined: Sun Apr 17, 2022 7:16 am

Re: In SDIO four wire mode, the file reading speed is very slow and the writing speed is normal

Postby Jinsc_esp32 » Mon Apr 18, 2022 2:10 pm

The speed of reading files using FatFs is normal
VeryCapture_20220418220932.png
VeryCapture_20220418220932.png (1.48 MiB) Viewed 3219 times

Who is online

Users browsing this forum: No registered users and 104 guests