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

User avatar
i_am_mrp
Posts: 27
Joined: Thu Sep 28, 2017 9:14 am
Location: California

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

Postby i_am_mrp » Fri Oct 27, 2017 9:05 am

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

scyu29
Posts: 0
Joined: Sat Oct 28, 2017 1:58 pm

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

Postby scyu29 » Sat Oct 28, 2017 2:07 pm

I got the same problem. Then I changed to use SDIO to connect SD card and fixed the problem

User avatar
i_am_mrp
Posts: 27
Joined: Thu Sep 28, 2017 9:14 am
Location: California

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

Postby i_am_mrp » Mon Oct 30, 2017 6:53 am

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

7amansharma
Posts: 8
Joined: Tue Jan 02, 2018 10:31 am

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

Postby 7amansharma » Tue Jan 02, 2018 10:39 am

@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 ?

User avatar
i_am_mrp
Posts: 27
Joined: Thu Sep 28, 2017 9:14 am
Location: California

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

Postby i_am_mrp » Tue Jan 02, 2018 6:57 pm

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.

7amansharma
Posts: 8
Joined: Tue Jan 02, 2018 10:31 am

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

Postby 7amansharma » Thu Jan 18, 2018 5:45 am

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.

vinimac
Posts: 24
Joined: Sun May 06, 2018 1:04 pm

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

Postby vinimac » Tue Nov 20, 2018 4:54 pm

Hi guys,

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

Who is online

Users browsing this forum: No registered users and 108 guests