cancel
Showing results for 
Search instead for 
Did you mean: 

STM32f4 with FatFS + FreeRTOS + SDIO SD card sometimes fails with FR_DISK_ERR on f_write

Dperr.1982
Associate II

My application works great, until it doesn't. I'm logging to an SD card, and every so often the call to f_write will return FR_DISK_ERR, at which point all subsequent attempts to write will return the same error.

Attempts to call f_open on a second file result in FR_LOCKED after the initial failure on the first file.

After a power cycle, everything is fine. And the mean time to failure is hours/thousands of log file writes (on two log files, not just one).

Documentation describes FR_DISK_ERR as an "unrecoverable hard error", but I'd like to figure out is there's any way at all to recover without power cycling.

Board layout follows guidance for SDIO lines, and the waveforms on the transmission lines look very similar to those on the ST dev boards. I can't totally rule out EMI as the root source, but would love to find a software work around since the application is tolerant of a few missed log entries.

11 REPLIES 11
GS1
Senior III

Hi all,

For anyone who has random problems when writing to SD Card on STM32H743: Try this!

I also had issues when writing to files and randomly got a "FR_DISK_ERR", which was originally caused by the SDMMC_ERROR_CMD_CRC_FAIL error described above.

From another thread I found the solution:

Temporarily setting SDMMCx->MASK = 0 in SDMMC_CmdReadMultiBlock and SDMMC_CmdWriteMultiBlock actually solved the problem!

Here is the changed Read routine:

  1. int32_t SDMMC_CmdReadMultiBlock(SDMMC_TypeDef *SDMMCx, uint32_t ReadAdd)
  2. {
  3. uint32_t maskReg = SDMMCx->MASK;
  4. SDMMCx->MASK = 0;
  5.  
  6.  
  7. SDMMC_CmdInitTypeDef sdmmc_cmdinit;
  8. uint32_t errorstate;
  9. /* Set Block Size for Card */
  10. sdmmc_cmdinit.Argument = (uint32_t)ReadAdd;
  11. sdmmc_cmdinit.CmdIndex = SDMMC_CMD_READ_MULT_BLOCK;
  12. sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;
  13. sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;
  14. sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;
  15. (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);
  16. /* Check for error conditions */
  17. errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_READ_MULT_BLOCK, SDMMC_CMDTIMEOUT);
  18.  
  19. SDMMCx->MASK = maskReg;
  20.  
  21.  
  22. return errorstate;
  23. }

Dperr.1982
Associate II

I was original poster on this thread. Last December I thought I had solved it by limiting SDIO peripheral access to a single FreeRTOS task, but I was wrong. What ultimately did work was assigning the task with SDIO peripheral access a higher priority than all other tasks. I haven't seen a single error now after thousands of hours of testing.