2017-08-11 01:33 PM
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.
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
2017-08-15 07:23 AM
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.