Skip to main content
Explorer
October 29, 2020
Solved

STM32F767 SDMMC DMA read missing first 16 bytes

  • October 29, 2020
  • 5 replies
  • 2359 views

My ongoing difficulties running FATFS on an SD card has uncovered a problem! A read of the boot sector does not read all the data correctly, specifically the first 16 bytes are all zero. This means that FATFS reports there is no filesystem.

The code I'm running is all CubeMX HAL stuff, so I'm at a loss what the problem is. 16 bytes is 1 DMA burst, so that might be significant. Here are screenshots of the SD boot sector, firstly as read by my PC, secondly as read during f_mount() by my STM32F767.

0693W0000059nS7QAI.png0693W0000059nSCQAY.png 

    This topic has been closed for replies.
    Best answer by Tesla DeLorean

    Do the DMA into the DTCM RAM (128K 0x20000000..0x2001FFFF), it is not cached

    Otherwise you have to properly manage the coherency

    5 replies

    Graduate II
    October 29, 2020

    Do the DMA into the DTCM RAM (128K 0x20000000..0x2001FFFF), it is not cached

    Otherwise you have to properly manage the coherency

    Explorer
    October 30, 2020

    I know there is an equivalent problem with the Ethernet DMA and previous colleagues have suggested putting Ethernet DMA buffers in SRAM2 and adding entries to the MPU to make them non-cacheable. Using DTCM seems easier to me, so can you confirm that I can DMA to DTCM without caching? I only ask because I've looked in the reference manual and haven't found an answer.

    Graduate II
    October 30, 2020

    Well on the F7 it is the least invasive solution. Note that the F74x/5x parts only have 64KB​.

    Not cached as the TCM is already single cycle and wide. DMA access is via a side-port.

    ST has some Clean/Invalidate code, but it has "over spray" issues when the buffers aren't on 32-byte boundaries. I wrote code to do this properly but it is more complex than the naive​ code provided. As I recall I special cased the memory region the buffer was in, and checked the alignment, and handled the corner cases at front/back.

    I had to do this for sure on the H7 as there is no winning move with regard to memory location.

    I​t is the deferred write buffering that is the biggest hazard. The MPU is one approach, but does cripple large swathes of memory.

    Graduate II
    October 29, 2020

    See 16-bytes here as cache is on 32-byte boundaries, ie 0x200252A0, 0x200252C0, 0x200252E0..

    This also gets to be VERY dangerous, as ByAddr variants of the DCache commands, as used by ST will have/cause collateral damage

    Explorer
    October 30, 2020

    Aargh, I was wondering if it's a caching problem. It's not my code that allocate the FATFS working buffers so it looks like my options are to modify library code or to turn caching off across the board.

    Graduate II
    October 30, 2020

    Can be handled at the DISKIO or BSP level by aggressively policing the buffer alignment issues.​ Could also decompose the requests, double-buffer, or use polled mode selectively.

    S​Ts solution for non 32-bit aligned buffers is to always use the least efficient method, rather than special case the worst, and optimize the other 99.99%

    Explorer
    November 4, 2020

    Just a quick update for anyone following this, the suggestion from @Community member​ is looking good and using DTCM for DMA buffers seems to be working.

    Visitor II
    May 15, 2024

    Hey,


    i run into the same Problem using FATFS with the SDMMC Peripheral on the STM32F746G with FreeRTOS.

    So I came across your two posts on this topic:
    https://community.st.com/t5/stm32-mcus-embedded-software/fatfs-on-sd-card-with-freertos-does-it-insist-on-using-dma/m-p/224600#M14523
    https://community.st.com/t5/stm32-mcus-products/stm32f767-sdmmc-dma-read-missing-first-16-bytes/m-p/230993#M51634

    I can read/write to the SD card via FATFS + SDMMC, but when i add FreeRTOS + DMA RX/TX Streams for the SDMMC the code stops working
    The issure is marked as solved here, could you elaborate what one have to do to get it to work?
    i.e. how to implement "Do the DMA into the DTCM RAM (128K 0x20000000..0x2001FFFF), it is not cached"

    Best regards,