cancel
Showing results for 
Search instead for 
Did you mean: 

SDIO(FatFS) File open(write) problem

Kim KyungTack
Associate III
Posted on April 03, 2018 at 05:35

Hi.

At the first time, SDIO works well but 10~20 minutes later, when i try to open a file(FA_CREATE_NEW | FA_WRITE options), there is no answer for 30 seconds and then SDIO does not work anymore after being shown FR_DISK_ERR.

Through debugging, I found that SDIO doesn't work as soon as the osMessageGet called on SD-Write function (osMessageGet result is osEventTimeout).

This problem disappears when the SDIO clock speed is lowered (ClockDiv is 8 or more). However, the Read/Write speed get very slow too much than i want.

STM32F429 use

CubeMX 4.25.0

STM32CubeF4 Firmware Package v1.21.0

FreeRTOS 9.0.0 (CMSIS 1.02)

FatFS R0.12c

SDIO Settings (DMA used)

0690X00000604XPQAY.jpg0690X00000604LGQAY.jpg0690X00000604UzQAI.jpg0690X00000604YCQAY.jpg
28 REPLIES 28
Posted on May 01, 2018 at 17:49

Getting there - thanks for setting me on the right path. There is indeed a spurious 'timeout' that breaks everything. This timeout is clock-speed dependent - that's probably why the OP didn't observe the problem with very slow SD clock - the problem was just very delayed. In my case, 48 MHz clock results in timeout during 01:30 minutes of idle. 24 MHz clock changes that to 3 minutes. I had SDMMC_HARDWARE_FLOW_CONTROL_ENABLE. This 'feature' caused the SD clock line to hang itself high and dry (in order to allow the DMA to catch up, apparently), forever, whenever the spurious timeout occurred. Looks like this feature is too dangerous when used alongside DMA, and most likely unneeded anyway.

It would be great to resolve why this timeout happens (SanDisk xtreme 32 GB, 0xffffffff programmed timeout), but I could work around it by disabling interrupts at the end of SD_DMAReceiveCplt(), and then by clearing all interrupt flags just before re-enabling the interrupts in both HAL_SD_ReadBlocks_DMA() and HAL_SD_WriteBlocks_DMA(). Would gladly post the code if anyone would find it useful - unfortunately the latest CubeMX code appears to have not been tested at all, and needed a lot of changes to sd_diskio.c (this is the version that uses message queues), bhp_driver_sd.c and even LWIP, to force its ram_heap to be DMA-friendly...

Posted on May 01, 2018 at 19:19

Running a F767ZI-NUCLEO (Rev A) with a 4-bit SDMMC implementation, STM32CubeF7 Firmware Package v1.9.0, not using CubeMX

I implemented a dwell test where it opens a file, adds a line, and closes, and then spins doing nothing for periods incrementing at 10 minute intervals.

Writing new line to DWELLLOG.TXT...

Waiting 0 minutes..Writing new line to DWELLLOG.TXT...

Waiting 10 minutes..Writing new line to DWELLLOG.TXT...

Waiting 20 minutes..Writing new line to DWELLLOG.TXT...

Waiting 30 minutes..Writing new line to DWELLLOG.TXT...

Waiting 40 minutes..Writing new line to DWELLLOG.TXT...

Waiting 50 minutes..Writing new line to DWELLLOG.TXT...

Doing a 60 minute wait currently, pretty confident this will run as long as I let it. Checks FATFS error results on all commands, and data written returned from f_write()

Will try and find a Z, everyone feel free to support my work...

Got a bunch of F746G-DISCO and F769I-DISCO running dataloggers for weeks on end.

Provide break down of SDMMC (w/Card Detect GPIO), USART, LED, HSE for these custom boards, I'll create a test build. If you think there are silicon issues ST will expect you to provide clear and convincing evidence and software that demonstrates the failure minimally.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on May 01, 2018 at 19:22

/**

  * @brief  Initializes the SD card device.

  * @retval SD status

  */

uint8_t BSP_SD_Init(void)

{

  uint8_t sd_state = MSD_OK;

  /* uSD device interface configuration */

  uSdHandle.Instance = SDMMC1;

  uSdHandle.Init.ClockEdge           = SDMMC_CLOCK_EDGE_RISING;

  uSdHandle.Init.ClockBypass         = SDMMC_CLOCK_BYPASS_DISABLE;

  uSdHandle.Init.ClockPowerSave      = SDMMC_CLOCK_POWER_SAVE_DISABLE;

  uSdHandle.Init.BusWide             = SDMMC_BUS_WIDE_1B;

  uSdHandle.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;

  uSdHandle.Init.ClockDiv            = SDMMC_TRANSFER_CLK_DIV;

  /* Msp SD Detect pin initialization */

  SD_Detect_MspInit();

  if (BSP_SD_IsDetected() != SD_PRESENT)

  {

    puts('No Card');

    return MSD_ERROR_SD_NOT_PRESENT;

  }

  /* Msp SD initialization */

  BSP_SD_MspInit(&uSdHandle, NULL);

  /* HAL SD initialization */

  if (HAL_SD_Init(&uSdHandle) != MSD_OK)

  {

        puts('HAL_SD_Init Failed');

    sd_state = MSD_ERROR;

  }

  /* Configure SD Bus width */

  if (sd_state == MSD_OK)

  {

    /* Enable wide operation */

    if (HAL_SD_ConfigWideBusOperation(&uSdHandle, SDMMC_BUS_WIDE_4B) != HAL_OK)

    {

      sd_state = MSD_ERROR;

    }

    else

    {

      sd_state = MSD_OK;

    }

  }

  return  sd_state;

}
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on May 02, 2018 at 16:07

Still going this morning...

Waiting 60 minutes..Writing new line to DWELLLOG.TXT...

Waiting 70 minutes..Writing new line to DWELLLOG.TXT...

Waiting 80 minutes..Writing new line to DWELLLOG.TXT...

Waiting 90 minutes..Writing new line to DWELLLOG.TXT...

Waiting 100 minutes..Writing new line to DWELLLOG.TXT...

Waiting 110 minutes..Writing new line to DWELLLOG.TXT...

Waiting 120 minutes..Writing new line to DWELLLOG.TXT...

Waiting 130 minutes..Writing new line to DWELLLOG.TXT...

Waiting 140 minutes..Writing new line to DWELLLOG.TXT...

Waiting 150 minutes..Writing new line to DWELLLOG.TXT...

Waiting 160 minutes..Writing new line to DWELLLOG.TXT...

Waiting 170 minutes..

And going...

Waiting 170 minutes..Writing new line to DWELLLOG.TXT...

Waiting 180 minutes..Writing new line to DWELLLOG.TXT...

Waiting 190 minutes..Writing new line to DWELLLOG.TXT...

Waiting 200 minutes..Writing new line to DWELLLOG.TXT...

Waiting 210 minutes..Writing new line to DWELLLOG.TXT...

Waiting 220 minutes..Writing new line to DWELLLOG.TXT...

Waiting 230 minutes..Writing new line to DWELLLOG.TXT...

Waiting 240 minutes..Writing new line to DWELLLOG.TXT...

Waiting 250 minutes..Writing new line to DWELLLOG.TXT...

Waiting 260 minutes..Writing new line to DWELLLOG.TXT...

Waiting 270 minutes..Writing new line to DWELLLOG.TXT...

Waiting 280 minutes..Writing new line to DWELLLOG.TXT...

Waiting 290 minutes..Writing new line to DWELLLOG.TXT...

Waiting 300 minutes..Writing new line to DWELLLOG.TXT...

Waiting 310 minutes..Writing new line to DWELLLOG.TXT...

Waiting 320 minutes..Writing new line to DWELLLOG.TXT...

Waiting 330 minutes..Writing new line to DWELLLOG.TXT...

Waiting 340 minutes..Writing new line to DWELLLOG.TXT...

Waiting 350 minutes..Writing new line to DWELLLOG.TXT...

Waiting 360 minutes..Writing new line to DWELLLOG.TXT...

Waiting 370 minutes..Writing new line to DWELLLOG.TXT...

Waiting 380 minutes..Writing new line to DWELLLOG.TXT...

Waiting 390 minutes..Writing new line to DWELLLOG.TXT...

Waiting 400 minutes..Writing new line to DWELLLOG.TXT...

Waiting 410 minutes..Writing new line to DWELLLOG.TXT...

Waiting 420 minutes..
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on May 08, 2018 at 08:41

Is you test-code working with the 1B transfer from your code below? 4B would be more realistic.

What divider/frequency do you use?

Would you care to share your whole project code? Would be interesting, if your code fails on my hardware..

Thank you very much!

Posted on May 08, 2018 at 14:56

I will need to check the speed setting, but pretty sure it is close to maximal, it is switching to 4-bit mode as the down stream initialization code shows.

To build a test binary I'd need board specifics as outlined above.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on May 08, 2018 at 16:15

Can't you make your code (or relevant sections / files) available? A binary would be problematic, as i use a custom hardware (which needs a lot of pin initialization and toggling to be workable with).

Posted on May 09, 2018 at 01:01

Well, in cases where I don't have to juggle 3 plates and stand on one foot for the SDIO/SDMMC to be functional at a board level, providing binaries yields decisive answers about where the issues are without getting in to day long arguments about my coding style/methodology, tool choices, or getting it to work/build on System X.

My role here is unpaid, so I'm looking to minimize the amount of time spent proving if things work or not, and to do so I frequently build on top of existing code I have confidence in.

Others reported this as impacting DMA usage

uSdHandle.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;

I'm reasonably confident that the examples in the HAL trees (ie FatFs, Display from SDCard, LTDC/DSI, JPEG, etc, from Cube F7 v1.9.0) don't go out to lunch in the manner described in the thread.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
DShin
Associate

I had a lot of trouble with the same problem. But I do not understand. I still do not have the skills to understand it.

Could you share the modified source?

developer2
Senior

Hi guys,

i'm not on time but i would like to share my experience ...

i used examples from ST's STM32 Cube package for STM32F4 version 1.24.0

i have same issue ... after 3 minutes i can't read any sector from SD card,

i used DMA access ...

i have workaround but it's not very fast ... steps:

  • first - reduce timeout value on rough calculation - it does not need to be 30 seconds, for example if my successful block transfer takes less than 1ms then i could set timeout 30 milliseconds - depends on clocking of peripheral ...
  • on timeout procedure do HAL_SD_DeInit()
  • then __HAL_RCC_SDIO_CLK_ENABLE(); __HAL_RCC_SDIO_FORCE_RESET(); __HAL_RCC_SDIO_RELEASE_RESET();
  • and then HAL_SD_Init();

finally it will need timeout 30ms but after peripheral restart it will come up with correct results ... this delay is acceptable for me ...

without reseting peripheral SDIO looks like it's frozen ... after 3 minutes, something like internal counter overflow - on overflow peripheral freezes ...

if somebody will write "idle" lines into text file on SD card then fragmentation on filesystem will happen ...

if you have some testcases i can try, please write ... i don't have any JTAG or debug devices ... i will try without debugging devices ...

Kind regards,