SDMMC2 on STM32F769NI Discovery

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderators: RoccoMarco, barthess

dflogeras
Posts: 212
Joined: Tue Sep 03, 2013 8:16 pm
Has thanked: 7 times
Been thanked: 19 times

SDMMC2 on STM32F769NI Discovery

Postby dflogeras » Tue Jun 05, 2018 7:44 pm

Hi,

I'm playing around with porting SQLite to this board. I'm using Chibi-18.2.1, since there were some changes to make SDMMC2 run smoothly out of the box in the 18.x.y series.

I am noticing that the disk IO keeps getting corrupted. It appears that if I call f_write/f_read with sizes that aren't multiples of block size (512) the data gets written or read incorrectly.

To test, I boiled it down to a simple loop that attempts to write a sequence of bytes that's not a multiple of 512, and read it back verifying that it's the same sequence I wrote.

This doesn't pass.

To be clear I'm not talking about STM32_SDC_SDMMC_UNALIGNED_SUPPORT. The byte buffer is always aligned (and I have DBG checks enabled for that). I am writing/reading non sector size number of bytes in each call to f_write and f_read.

Is this a known bug? Common problem? I'm 99% sure that I didn't see this issue before when I played with disk stuff before, but that was using the SPI MMC driver, different Chibi, and whatever fatfs came with the 16.x.y series.

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: SDMMC2 on STM32F769NI Discovery

Postby Giovanni » Tue Jun 05, 2018 8:51 pm

Hi,

Never seen this but I don't use FatFS much, the SDC driver only handles 512 bytes blocks so it could be something in FatFS, it is there that small writes should be buffered.

Corrupted how exactly? data missing, shifted, masked?

Giovanni

User avatar
wurstnase
Posts: 121
Joined: Tue Oct 17, 2017 2:24 pm
Has thanked: 43 times
Been thanked: 30 times
Contact:

Re: SDMMC2 on STM32F769NI Discovery

Postby wurstnase » Wed Jun 06, 2018 2:57 am

Probably I'm wrong, but isn't the write access buffered? AFAIK you need to close file and/or unmount the SD card. Like Windows "secure remove".

When you try to write and read immediately in size smaller then the SD card buffer, you will not read the same, because it hasn't been written finally.
\o/ Nico

steved
Posts: 823
Joined: Fri Nov 09, 2012 2:22 pm
Has thanked: 12 times
Been thanked: 135 times

Re: SDMMC2 on STM32F769NI Discovery

Postby steved » Wed Jun 06, 2018 8:30 am

Have you considered memory caching in your driver? Unless you can guarantee that data is always in non-cacheable RAM (and I'm not sure that you can), this is necessary.

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: SDMMC2 on STM32F769NI Discovery

Postby Giovanni » Wed Jun 06, 2018 10:27 am

steved wrote:Have you considered memory caching in your driver? Unless you can guarantee that data is always in non-cacheable RAM (and I'm not sure that you can), this is necessary.


Good point.

Giovanni

dflogeras
Posts: 212
Joined: Tue Sep 03, 2013 8:16 pm
Has thanked: 7 times
Been thanked: 19 times

Re: SDMMC2 on STM32F769NI Discovery

Postby dflogeras » Wed Jun 06, 2018 2:36 pm

Giovanni wrote:
Never seen this but I don't use FatFS much, the SDC driver only handles 512 bytes blocks so it could be something in FatFS, it is there that small writes should be buffered.
Giovanni


I agree, I did a quick inspection of the fatfs code and it seems to only write sectors when they are full, or upon f_sync/f_close and it writes a full sector even if it has not been filled (the filesystem takes care of how much is valid). That being said, it could have a bug.


Giovanni wrote:Corrupted how exactly? data missing, shifted, masked?

Giovanni


It's weird, when I read it in the debugger in-situ, it seems like it is all numbers I wrote, but wrapped around after it fails comparing the 3rd chunk. However, if I unmount the card and read it on my PC with a hex editor, what is on the disk starts with my sequence, then has garbage in it (including a lot of 0x55555555 which looks like it has written memory that the stack filler initialized).

I will attach the shortest example I can come up with. It was based on the LWIP-FATFS-USB demo, and then pared down and modified to run on my F749 discovery. You could easily modify it to run on another board, but would need to change to SDMMC1 probably. If you change #define CHUNKSIZE from 406 to 4096, it works as expected. Just unzip it into the top folder of ChibiOS-18.2.0 (and unzip ext/fatfs as well).

Also note, I have ffconf.h set up for multipartition since my card has a partition table on it. You might need to switch that, and the second argument f_mount call if you have a more traditional non-partitioned sdcard.

sd.zip
example
(20.61 KiB) Downloaded 152 times


Dave

dflogeras
Posts: 212
Joined: Tue Sep 03, 2013 8:16 pm
Has thanked: 7 times
Been thanked: 19 times

Re: SDMMC2 on STM32F769NI Discovery

Postby dflogeras » Wed Jun 06, 2018 2:39 pm

wurstnase wrote:Probably I'm wrong, but isn't the write access buffered? AFAIK you need to close file and/or unmount the SD card. Like Windows "secure remove".

When you try to write and read immediately in size smaller then the SD card buffer, you will not read the same, because it hasn't been written finally.


Thanks for the suggestion Nico, but I don't think this is the case. The issue happens even if I just call f_write without reading it back, and then unmount the card properly. When you call f_read, the fatfs layer should be smart enough to take care of what is buffered, and what needs to be read off the disk. Just to be pedantic, I added a f_sync() call between each write/read to no avail either.

Dave

dflogeras
Posts: 212
Joined: Tue Sep 03, 2013 8:16 pm
Has thanked: 7 times
Been thanked: 19 times

Re: SDMMC2 on STM32F769NI Discovery

Postby dflogeras » Wed Jun 06, 2018 2:45 pm

Giovanni wrote:
steved wrote:Have you considered memory caching in your driver? Unless you can guarantee that data is always in non-cacheable RAM (and I'm not sure that you can), this is necessary.


Good point.

Giovanni


Hmm, steved is on to it!

I noted that in the STM32F76xxI.ld file, that the main stack and BSS are in ram3 which is DTCM ram. The HEAP is in regular SRAM. If I changed the buffer in my main.c from in BSS to be malloc'd, the problem disappears.

Not sure what that totally implies, but it will help Giovanni I'm sure.

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: SDMMC2 on STM32F769NI Discovery

Postby Giovanni » Wed Jun 06, 2018 5:32 pm

hi,

It is because BSS is allocated (by default) in a non-cached RAM, this way the problem is less impacting on developers but it is there. I cannot put everything in the fast RAM because it is not so big.

There is already a bug opened about FatFS and caching, probably it will get a more general solution at some point.

See the linker script to understand how the various areas are assigned to the various RAMs, there is a lot of space for tweaking.

Giovanni

steved
Posts: 823
Joined: Fri Nov 09, 2012 2:22 pm
Has thanked: 12 times
Been thanked: 135 times

Re: SDMMC2 on STM32F769NI Discovery

Postby steved » Wed Jun 06, 2018 8:53 pm

I just modified the FatFs diskio.c file to manage the buffer flushing:

Code: Select all

DRESULT disk_read (
    BYTE pdrv,        /* Physical drive number (0..) */
    BYTE *buff,       /* Data buffer to store read data */
    DWORD sector,     /* Sector address (LBA) */
    UINT count        /* Number of sectors to read (1..255) */
)
{

  switch (pdrv) {
#if HAL_USE_SDC
  case LOGICAL_SDC :
    if (blkGetDriverState(&SDCD1) != BLK_READY)
      return RES_NOTRDY;
    if (buff > (BYTE *)&(__ram3_end__))
      dmaBufferInvalidate(buff, count * MMCSD_BLOCK_SIZE);

    if (sdcRead(&SDCD1, sector, buff, count))
      return RES_ERROR;
    return RES_OK;
#endif
  }
  return RES_PARERR;
}



/*-----------------------------------------------------------------------*/
/* Write Sector(s)                                                       */

#if !FF_FS_READONLY
DRESULT disk_write (
    BYTE pdrv,        /* Physical drive number (0..) */
    const BYTE *buff, /* Data to be written */
    DWORD sector,     /* Sector address (LBA) */
    UINT count        /* Number of sectors to write (1..255) */
)
{
  switch (pdrv) {
#if HAL_USE_SDC
  case LOGICAL_SDC :
    if (blkGetDriverState(&SDCD1) != BLK_READY)
      return RES_NOTRDY;
    if (buff > (BYTE *)&(__ram3_end__))
      dmaBufferFlush(buff, count * MMCSD_BLOCK_SIZE);
    if (sdcWrite(&SDCD1, sector, buff, count))
      return RES_ERROR;
    return RES_OK;
#endif
  }
  return RES_PARERR;
}

Not sure whether there's any advantage to checking whether the buffer is in cached RAM, but it didn't seem to do any harm.
I've also adjusted my malloc() to assign memory starting on 32-byte boundaries (i.e. cache lines)


Return to “STM32 Support”

Who is online

Users browsing this forum: No registered users and 26 guests