cancel
Showing results for 
Search instead for 
Did you mean: 

FatFs fails randomly with V1.11

Lars Beiderbecke
Senior III
Posted on May 11, 2018 at 15:32

I'm using FatFs with SDMMC1 on a Nucleo STM32F722ZE with CubeMX 4.25.

My project uses FatFs to manipulate a MicroSD card, but I noticed that many operations just fail randomly, usually with FR_DISK_ERR.  For example, in this code snippet published my ElmChan to copy files

// example: fcopy('file1', 'folder/file1'):

f_open(&src->fh, from_path, FA_READ);  // src, dst are global

f_open(&dst->fh, to_path, FA_WRITE | FA_CREATE_ALWAYS);  // to_path is file

while (1) {

  f_read(&src->fh, buffer, sizeof(buffer), &br);

  if (br == 0)

    break; // eof

  f_write(&dst->fh, buffer, br, &bw);  // <-------------------------------

}

f_close(&src->fh);

f_close(&dst->fh);

the f_write would often fail when running in Run or in Debug mode.  On the other hand, it usually works when single stepping through this code.

But there are other functions that may fail, for example f_readdir().

I do not use DMA, not RTOS, and disabled the SDMMC1 interrupt. I'm using the stock function generated by CubeMX.

How can I fix the failing functions? Are FatFs functions executed serialized, or can two functions execute interleaved concurrently?

1 ACCEPTED SOLUTION

Accepted Solutions
Lars Beiderbecke
Senior III
Posted on May 11, 2018 at 19:43

I finally resolved my problem by reducing the SDMMC1 clock via the SDMMC1 Clock Divider. This makes sense as my uSD card is only attached through wires and a breakout gadget.

I had increased the Clock Divider before without effect, but I just noticed that the Clock Divider Bypass was set.  m)

View solution in original post

9 REPLIES 9
Posted on May 11, 2018 at 15:46

I don't think any of the FatFs or SDMMC/SDIO interaction is serialized, beyond you keeping stuff in a singular thread, which I'd recommend over mutexes. ie have a state machine that handle files interactions in a singular place, and round-robins to the next action if it would otherwise block waiting for data from some other thread.

Looking at the top level code is pointless, errors and details are not propagated. You need to instrument and review interaction at the DISKIO layer, and pull the ErrorCode from the SDMMC/SDIO object. The most prevalent cascading error is an underrun on a write. If you have a display on the LTDC you need to be using DMA.

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 11, 2018 at 15:50

Fair enough, but what I meant was if I call f_read and then f_write, will f_read be finished before I start f_write? I assume yes.

EDIT: I reread your answer, this is what you're saying. 🙂

Posted on May 11, 2018 at 15:57

In a singular thread of operation you will be safe, concurrent operation can be difficult to pull off successfully. Not saying it can't be done*, but it gets very complex and most people run into deadlocks when they don't take locks consistently. The simple/elegant approach will be more robust, and especially if the dev team has size or turnover.

*In a previous life I wrote drivers and file systems on WinNT systems, with multi-threads, and multi-processors, and an async IO stack.

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

I finally resolved my problem by reducing the SDMMC1 clock via the SDMMC1 Clock Divider. This makes sense as my uSD card is only attached through wires and a breakout gadget.

I had increased the Clock Divider before without effect, but I just noticed that the Clock Divider Bypass was set.  m)

James Murray
Senior
Posted on May 11, 2018 at 22:43

On the STM32F769I, I found that the SDMMC code doesn't work correctly. In non-DMA mode it is too slow to keep up with the SDMMC module and reads overrun. I optimised the code by removing kruft and got it to work ok at full clock speed.

James

Posted on May 12, 2018 at 13:09

I'm aiming for DMA, which didn't work so far. But I guess I'll postpone that until I move to my real board with proper routing to the SD socket.

Posted on May 12, 2018 at 13:55

DMA should be viable, the interface is clocking at the same speed regardless. Would perhaps remove SB116/SB117 to eliminate the stubs, but I have SDMMC+DMA running on F7 NUCLEO boards without that at >50MHz. Using a microsd socket board with pull-ups and 3' schmartboard wires.

DMA memory/cache coherency can be an issue, but using DTCMRAM should entirely side step that. On the F722 that should be 64KB at 0x20000000 as I recall.

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 13, 2018 at 16:55

Regarding the pull-ups, the are conflicting recommendations on the web.

Do you think the internal pull-ups of the STM32F722 are sufficient, or do I need external pull-ups, possibly close to the SD card?

Posted on May 13, 2018 at 19:15

I've seen designs without pull-ups at the socket work and some that fail. My preference is for pull-up's at the socket, and with high bandwidth short signal runs the use of 22R series resistors can reduce ringing issues, as can backing off the slew-rate settings. ST calls them speed settings, but they are how aggressively you want to drive the pins, and assume a certain amount of load and lead lengths. ie you don't need 100 MHz setting to get sharp ns rise times into negligible capacitive load.

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