Hello,
- So after running into problems with the M7 cache coherency and my SPI driver (thanks to Giovanni for helping me with that!) I also found that the same problems occur when using the FatFS libary on the M7-platform.
- Currently I am using ChibiOS_16.1.8
- Compiled with gcc-arm-none-eabi-5_4-2016q2
- The board I have tested this on is the STM32F746G-DISCO in Eclipse.
- The problem occurs when trying to read from or write to the disk with FatFS and the FIL-variable passed to the read/write function is allocated from the heap. When using chHeapAlloc to allocate the FIL-variable nothing is returned when reading from and nothing is written when writing to the disk. This also occurs when creating a thread with 'chThdCreateFromHeap' and the FIL-variable is created in the thread, because then it is also allocated from the heap.
- The reason for the failure is that the FIL-variable isn't flushed to cache when writing and isn't being invalidated when reading from the disk.
- In the attachment I have included a fix for this in the fatfs_diskio.c file. The only thing I am not sure of, is if it's allowed to use the 'MMCSD_BLOCK_SIZE' define to determine the size of the buffer to flush/invalidate. I have tested this implementation for the SDC-interface and so far it works fine.
cpu20
Cortex-M7 platform FatFS Cache coherency Topic is solved
Cortex-M7 platform FatFS Cache coherency Topic is solved
- Attachments
-
- Patched_diskio.zip
- (1.59 KiB) Downloaded 283 times
Re: Cortex-M7 platform FatFS Cache coherency
There are a couple of possible issues here:
1. The heap could be assigned to non-cacheable RAM (especially with Chibi's ability to support multiple memory allocators). So the flushing/invalidating of buffers could be at best a waste of CPU cycles, and at worst a problem.
2. The buffer may not be aligned to cache lines. In that situation I had to flush an extra line - most likely benign when flushing, but potentially problematical when invalidating cache. The preferred fix for this is obviously to ensure the buffer is aligned to a cache line. (Chibi's heap allocator could support this, but at present CH_HEAP_ALIGNMENT is hard-coded into chheap.h. Maybe it should become an overrideable value.)
1. The heap could be assigned to non-cacheable RAM (especially with Chibi's ability to support multiple memory allocators). So the flushing/invalidating of buffers could be at best a waste of CPU cycles, and at worst a problem.
2. The buffer may not be aligned to cache lines. In that situation I had to flush an extra line - most likely benign when flushing, but potentially problematical when invalidating cache. The preferred fix for this is obviously to ensure the buffer is aligned to a cache line. (Chibi's heap allocator could support this, but at present CH_HEAP_ALIGNMENT is hard-coded into chheap.h. Maybe it should become an overrideable value.)
- Giovanni
- Site Admin
- Posts: 14457
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: Cortex-M7 platform FatFS Cache coherency
I think steved is correct, a proper fix would require changes in FatFS because all buffers should be aligned to cache lines.
The best option is to allocate FatFS data in a non-cacheable RAM section.
Giovanni
The best option is to allocate FatFS data in a non-cacheable RAM section.
Giovanni
Re: Cortex-M7 platform FatFS Cache coherency
Hi Giovanni,
Can you share where and how you set the FatFS in the Non-Cacheable memory? I have stm32h743 with cache memory enabled on it, and the FatFS does not work with it.
Can you share where and how you set the FatFS in the Non-Cacheable memory? I have stm32h743 with cache memory enabled on it, and the FatFS does not work with it.
- Giovanni
- Site Admin
- Posts: 14457
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: Cortex-M7 platform FatFS Cache coherency
Hi,
It is not easy and I haven't done this yet.
FatFS does not prefix its own variable names with a common prefix so you can't make a linker script allocating all of them to a specific section.
You should find all variable declarations in ff.c and add __attribute__((section("section"))) to each of them. "section" would then be loaded in a non cacheable RAM.
For example .ram3_init.fatfs for initialized variables and .ram3_clear.fatfs for uninitialized variables (there is an option in mcuconf.h to make RAM3 non cacheable).
Giovanni
It is not easy and I haven't done this yet.
FatFS does not prefix its own variable names with a common prefix so you can't make a linker script allocating all of them to a specific section.
You should find all variable declarations in ff.c and add __attribute__((section("section"))) to each of them. "section" would then be loaded in a non cacheable RAM.
For example .ram3_init.fatfs for initialized variables and .ram3_clear.fatfs for uninitialized variables (there is an option in mcuconf.h to make RAM3 non cacheable).
Giovanni
- alex31
- Posts: 379
- Joined: Fri May 25, 2012 10:23 am
- Location: toulouse, france
- Has thanked: 38 times
- Been thanked: 62 times
- Contact:
Re: Cortex-M7 platform FatFS Cache coherency
Hello,
I think, the only time where stack allocated variable are passed to disk_xxx function are at file opening when LFN = 2 is choosen.
otherwise, having the fatfs object declared is a no dma section (ram3 for the F7) should be enough.
One think that can be done to quickly find all the problems and to only declare the few variables that need to be in dma compatible section is to instrument the 3 disk_xxx functions with an assert :
for the F7, assuming the standard .ld linker script adding this line and compiling in with ASSERT enabled will trap the errors :
chDbgAssert((buff >= (BYTE *)0x20000000) && (buff <= (BYTE *)0x20000000 + (128U * 1024U)),
"not dma compatible ram3 segment");
Alexandre
I think, the only time where stack allocated variable are passed to disk_xxx function are at file opening when LFN = 2 is choosen.
otherwise, having the fatfs object declared is a no dma section (ram3 for the F7) should be enough.
One think that can be done to quickly find all the problems and to only declare the few variables that need to be in dma compatible section is to instrument the 3 disk_xxx functions with an assert :
for the F7, assuming the standard .ld linker script adding this line and compiling in with ASSERT enabled will trap the errors :
chDbgAssert((buff >= (BYTE *)0x20000000) && (buff <= (BYTE *)0x20000000 + (128U * 1024U)),
"not dma compatible ram3 segment");
Alexandre
Re: Cortex-M7 platform FatFS Cache coherency
Here is how I solve that issue on STM32H743:
https://yairgadelov.me/2021/11/setup-sd ... mcu/#cache
https://yairgadelov.me/2021/11/setup-sd ... mcu/#cache
Who is online
Users browsing this forum: Bing [Bot] and 10 guests