cancel
Showing results for 
Search instead for 
Did you mean: 

SDIO FatFS Problems without Delays Between Block Writes

John Craven
Senior
Posted on August 11, 2017 at 22:33

I have been playing with 4bit SDIO and FatFS.

I was able to get good write speeds (8-9 MB/s) but i would often get errors and the SD card lock up. No read/write.

Project is CUBE 4.0 generated for the STM32-407G-Disco1 board.

After a lot of testing with different hardware for the SD card holder/circuit, i have found this is code based issue.

App is simple.

  • If user button is held on startup, then format the card
  • If not, write N files, of a given file size, using a given buffer/block size.
  • Calculate the average write rate.

Works great, but only if i add a short delay, HAL_Delay(1) after each f_write, see line

If the delay is not present, the SD locks up randomly a few writes to a few files.

With 1ms delay and it works great all day, can write any number of files, any file size, any buffer/chunk size until the SD card is full. Filled many 32GB cards. Data on card has been validated.

Using 32kB writes, i get 8.5MB/s. I can live with that.

I had tested multiple SD cards and SD holder/circuits. It don't think its hardware.

I understand SD card latency issues.

Any latency, and waiting should done/handled in the drivers, and not require my arbitrarywaiting between writes.

Why does my test writing always fail, without the 1ms delay after each block write?

Full project is attached. Only file changed for Cube generation is main.c

/* Includes ------------------------------------------------------------------*/
#include 'main.h'
#include 'stm32f4xx_hal.h'
#include 'fatfs.h'
#include 'sdio.h'
#include 'tim.h'
#include 'gpio.h'
/* USER CODE BEGIN Includes */
#include 'string.h'
/* USER CODE END Includes */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
SD_HandleTypeDef hsd;
HAL_SD_CardInfoTypeDef SDCardInfo;
FATFS fatfs; /* FAT File System */
FRESULT fresult; /* FAT File Result */
#define TESTLENGTH 1
#define FILESIZE (0x100000 * 1024) //1MB x A
#define CHUNKSIZE (0x000400 * 32) //1KB x B
#define chunks (FILESIZE/CHUNKSIZE)
char bigbuffer[CHUNKSIZE];
int numfileswritten = 0;
uint32_t totaltime;
uint32_t filetime;
uint32_t chunktime;
uint32_t avgperiod;
float rate;
uint32_t timeout;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE END PFP */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
int main(void) {
 /* USER CODE BEGIN 1 */
 /* USER CODE END 1 */
 /* MCU Configuration----------------------------------------------------------*/
 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();
 /* USER CODE BEGIN Init */
 /* USER CODE END Init */
 /* Configure the system clock */
 SystemClock_Config();
 /* USER CODE BEGIN SysInit */
 /* USER CODE END SysInit */
 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_SDIO_SD_Init();
 MX_FATFS_Init();
 MX_TIM2_Init();
 /* USER CODE BEGIN 2 */
 //fill buffer with some data for external checks
 for (int i = 0; i < CHUNKSIZE; i++) {
 bigbuffer[i] = 0x21 + i % 0x50;
 }
 //1us count up 32bit timer for rate calcs
 HAL_TIM_Base_Start(&htim2);
 if (BSP_SD_Init() == MSD_OK) {
 //mount sd
 fresult = f_mount(&fatfs, (TCHAR const*) SD_Path, 0);
 //if user button is pressed then reformat the sd
 if (HAL_GPIO_ReadPin(BUT_GPIO_Port, BUT_Pin) == GPIO_PIN_SET) {
 HAL_GPIO_WritePin(LD6_GPIO_Port, LD6_Pin, GPIO_PIN_SET);
 fresult = f_mkfs((TCHAR const*) SD_Path, 0, 0);
 HAL_GPIO_WritePin(LD6_GPIO_Port, LD6_Pin, GPIO_PIN_RESET);
 HAL_Delay(1000);
 } else {
 //if mount and/or format are good, start writing files
 if (fresult == FR_OK) {
 int fn = 0;
 while (fn < TESTLENGTH) {
 char fnbuffer[32];
 snprintf(fnbuffer, sizeof(char) * 32, 'data%i.txt', fn);
 FIL myfile;
 fresult = f_open(&myfile, fnbuffer,
 FA_CREATE_ALWAYS | FA_WRITE);
 if (fresult == FR_OK) {
 long count = 0;
 UINT bw;
 //turn of green LED on while writing
 HAL_GPIO_WritePin(LD4_GPIO_Port, LD4_Pin, GPIO_PIN_SET);
 //write chunks
 while (count++ < chunks) {
 //Tried checking SD status before writing (without delay), but doesn't fix problem
 //========================================================================
 //timeout = SD_DATATIMEOUT;
 //while(BSP_SD_GetCardState()!= MSD_OK)
 //{
 // if (timeout-- == 0)
 // {
 // return 0;
 // }
 //}
 //========================================================================
 //reset timer
 __HAL_TIM_SET_COUNTER(&htim2, 0);
 //write the a chunk
 fresult = f_write(&myfile, bigbuffer, CHUNKSIZE, &bw);
 //add timer count to total write time
 totaltime += __HAL_TIM_GET_COUNTER(&htim2);
 //Works with this delay, but is unreliable without this delay
 //========================================================================
 HAL_Delay(1);
 //========================================================================
 }
 fresult = f_close(&myfile);
 //turn of green LED between files
 HAL_GPIO_WritePin(LD4_GPIO_Port, LD4_Pin,
 GPIO_PIN_RESET);
 //update rate calcs
 numfileswritten++;
 avgperiod = totaltime / numfileswritten;
 rate = (float) FILESIZE / (float) avgperiod;
 fn++;
 //short pause just to see when file write ends on green led
 HAL_Delay(100);
 } else {
 //red LED for mount/format error
 HAL_GPIO_WritePin(LD5_GPIO_Port, LD5_Pin, GPIO_PIN_SET);
 break;
 }
 }
 }
 }
 }
 //orange LED
 HAL_GPIO_WritePin(LD3_GPIO_Port, LD3_Pin, GPIO_PIN_SET);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1) {
 /* USER CODE END WHILE */
 /* USER CODE BEGIN 3 */
 HAL_Delay(1);
 }
 /* USER CODE END 3 */
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

#stability #sdio #delays #fatfs
1 REPLY 1
John Craven
Senior
Posted on August 15, 2017 at 16:23

Based on some other SDIO FatFS posts, i have additionally tried;

1) Enabling SDIO flowcontrol.

hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_ENABLE;�?�?�?

This did not allow removal of the HAL_Delay. But it causes errors with the delays!!! So that'sthe issue or a solution.

2) I tried slowing the SDIO clock;

hsd.Init.ClockDiv = 1;�?�?

With delays, my write throughput dropped for 8.5MB/s to 6.4MB/s.

Without delays, my writes fails, same as full clock speed.