Page 1 of 1

uSD card using SPI and fwrite() consistently fails after short operating period

Posted: Fri Oct 27, 2017 9:05 am
by i_am_mrp
IDF: pull/update of latest on: Oct 25, 2017 -- 5pm EST
Code: Modified IDF example
Board: Adafruit ESP32 Huzzah Feather - silicon rev: 1
SD Breakout: Adafruit MicroSD card breakboard+ pid: 254 (2 test boards)
SD Cards: SanDisk 8GB Class-4 SDHC (2 test cards)
All breakout-board & SD-card physical test combinations fail.
Physical pull-ups are used the 4 wire connections.
A separately monitored and verified power source is used for the SD card breakout.
The cards are formatted and verified in other use cases (sustained video and audio storage scenarios)

I saw issue #1089 regarding timeouts and this is not an issue in this case as the time for each fwrite is way below the timeout values.

The number of fwrites varies between runs but always fails. Using different size data buffers does not seem to matter as the fwrite will eventually fail anyways. The failure can occur after a few 100 writes or after a few 1000 but always fails and fails at different number of writes between tests.

I looked at fflush(..) and fsync(..) in case some buffering or write-thru was being a problem and when I interspersed them in the write loop every X writes, they did not stop the failure from occurring.

The failure does not seem capacity related as the cards are being used at under 1% capacity

The code does not do any yield/delay as it is not running long enough for the watchdog to complain.

Code and output follow:

Code: Select all

#include <stdio.h>
#include <string.h>
#include <sys/unistd.h>
#include <sys/stat.h>

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#include "esp_vfs_fat.h"
#include "driver/sdmmc_host.h"
#include "driver/sdspi_host.h"
#include "sdmmc_cmd.h"

void app_main(void) { // app_main_sd_card_issues
	char *TAG = "example";
    sdmmc_host_t host = SDSPI_HOST_DEFAULT();  // default is SDMMC_HOST_FLAG_SPI
    	host.max_freq_khz = SDMMC_FREQ_DEFAULT ;	  // 20kHz

    	// DMA ch: 1, no CD or WP
    sdspi_slot_config_t slot_config = SDSPI_SLOT_CONFIG_DEFAULT();
		slot_config.gpio_miso = 18;
		slot_config.gpio_mosi = 19;
		slot_config.gpio_sck  = 5;
		slot_config.gpio_cs   = 21;

    esp_vfs_fat_sdmmc_mount_config_t mount_config = {
        .format_if_mount_failed = false,
        .max_files = 10
    };

    sdmmc_card_t* card;
    ESP_ERROR_CHECK(esp_vfs_fat_sdmmc_mount("/sdcard", &host, &slot_config, &mount_config, &card));

    sdmmc_card_print_info(stdout, card);

    const char* filePath = "/sdcard/data.txt" ;
	struct stat st;
	if (stat(filePath, &st) == 0) {
		unlink(filePath);  // if old file exists, delete it
	}

    ESP_LOGI(TAG, "Opening %s", filePath);
    FILE* f = fopen(filePath, "w");
    if (f == NULL) {
        ESP_LOGE(TAG, "Failed to open %s for writing", filePath);
        return;
    }

    int BUF_SIZE = 1024 ;
    char * buf= malloc(BUF_SIZE);
    memset(buf, 'x', BUF_SIZE) ;

    // An fwrite(..) will consistently fail in this loop after random/various iterations
    int i, wrote, num_records = 3 * 60 * 60  ; // NEVER finishes this many
	for(i = 1; i <= num_records; i++) {
		wrote = fwrite(buf, 1, BUF_SIZE, f) ;
		if (wrote != BUF_SIZE) {
			ESP_LOGE(TAG, "Failed on fwrite(..) with: %d", wrote) ;
			break ;  // after 1st failure, all successive fwrite(..)'s also fail...
		}

		if (i % 100 == 0){
			ESP_LOGI(TAG, "written records: %d, bytes: %d", i, i * BUF_SIZE) ;
//			vTaskDelay(10 / portTICK_PERIOD_MS);  // appease watchdog
		}
	}
    fclose(f);

    ESP_ERROR_CHECK(esp_vfs_fat_sdmmc_unmount());
    ESP_LOGI(TAG, "Card unmounted");

    free(buf) ;
}
Name: SS08G
Type: SDHC/SDXC
Speed: default speed
Size: 7580MB
CSD: ver=1, sector_size=512, capacity=15523840 read_bl_len=9
SCR: sd_spec=2, bus_width=5
I (353) example: Opening /sdcard/data.txt
I (763) example: written records: 100, bytes: 102400
I (1013) example: written records: 200, bytes: 204800
I (1263) example: written records: 300, bytes: 307200
I (1513) example: written records: 400, bytes: 409600
I (1753) example: written records: 500, bytes: 512000
I (2003) example: written records: 600, bytes: 614400
I (2253) example: written records: 700, bytes: 716800
I (2503) example: written records: 800, bytes: 819200
I (2753) example: written records: 900, bytes: 921600
I (3003) example: written records: 1000, bytes: 1024000
I (3243) example: written records: 1100, bytes: 1126400
I (3493) example: written records: 1200, bytes: 1228800
I (3743) example: written records: 1300, bytes: 1331200
E (4093) sdspi_host: sdspi_host_start_command: cmd=25 error=0x107
E (4093) sdmmc_cmd: sdmmc_write_sectors_dma: sdmmc_send_cmd returned 0x107
E (4093) diskio_sdmmc: sdmmc_write_blocks failed (263)
E (4103) example: Failed on fwrite(..) with: 0
E (4103) sdspi_host: sdspi_host_start_command: cmd=24 error=0x108
E (4113) sdmmc_cmd: sdmmc_write_sectors_dma: sdmmc_send_cmd returned 0x108
E (4123) diskio_sdmmc: sdmmc_write_blocks failed (264)
I (4123) example: Card unmounted

Re: uSD card using SPI and fwrite() consistently fails after short operating period

Posted: Sat Oct 28, 2017 2:07 pm
by scyu29
I got the same problem. Then I changed to use SDIO to connect SD card and fixed the problem

Re: uSD card using SPI and fwrite() consistently fails after short operating period

Posted: Mon Oct 30, 2017 6:53 am
by i_am_mrp
Thank you for the suggestion. However my designs, circuitry, breakouts etc... are for SPI.

Is this a known bug of ESP-IDF? I did not find any such mention in the ESP-IDF GitHub issues.

Is this problem indicative of overall SPI stability with ESP32?

Can Espressif please comment on this?

Thank you

Re: uSD card using SPI and fwrite() consistently fails after short operating period

Posted: Tue Jan 02, 2018 10:39 am
by 7amansharma
@i_am_mrp
hey i am having the same problem using uSdcard with spi in esp32.
After getting timeout errors sometimes it get fixed automatically or sometimes i have to put re-initialization code for sd card there to fix which does not solves the problem in first try.
It takes multiple mounting and de-mounting of sd card to fix this error.
Did you find any solution for this ?

Re: uSD card using SPI and fwrite() consistently fails after short operating period

Posted: Tue Jan 02, 2018 6:57 pm
by i_am_mrp
I have not found a solution. I tried various level API's to do the card IO but always the same repeatable problem.

There were some previous forum/internet discussions on timeouts related to SD card operations so search for that and there may be an answer for your timeout issues.

I have tried multiple boards and countless IDF updates to see if this problem gets fixed/addressed, but no luck.

I even use the Espressif Wrover board that has the microSD on the board and same issue. Given the large number of various boards and various SD card sockets I have tried, I can only conclude it is a SW problem somewhere in IDF.

I will be looking at this problem again in a few weeks. Please post if you find anything in the mean time.

Re: uSD card using SPI and fwrite() consistently fails after short operating period

Posted: Thu Jan 18, 2018 5:45 am
by 7amansharma
we didn't find any solution too.
Now,we changed our pcb design and switched to 1 line SD mode that works without any problem.

Re: uSD card using SPI and fwrite() consistently fails after short operating period

Posted: Tue Nov 20, 2018 4:54 pm
by vinimac
Hi guys,

I have same problem, and I am using SD MMC mode. I solved by calling taskYIELD() after fwrite().