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) ;
}
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