2021-05-21 01:16 PM
Hi,
I am facing a strange cache problem. I use the DCMI coupled to the DMA in order to acquire an image into the external SDRAM. As indicated in the application note AN4839, I proceed in this way.
Everything work perfectly on the stm32H7.
On the stm32F7, as soon as the cache invalidation routine is called, the CPU generates a bus error.
On the stm32F7, in the DMA interruption indicating the end of the transfer, I replaced the cache invalidation (cache_D_Invalidate();) by the cache clean followed by the cache invalidation (cache_D_Clean(); cache_D_Invalidate();). Adding a clean (cache_D_Clean();) seems to avoid the bus error but I cannot understand why.
Why the behavior of the H7 and the F7 caches are different on the same code?
Thank you for your feedbacks.
Any idea why ?
Solved! Go to Solution.
2021-05-22 08:20 AM
The functions, which clean/invalidate the whole cache, normally should not be used at all and are almost useless. Typically I-cache can just be enabled and doesn't require any further management. For D-cache a proper management has to follow 3 basic rules:
Yes, even for receive part the invalidation must be done before passing buffers to DMA, because otherwise cache eviction can damage the receive buffers by writing back dirty lines during reception. A cite from AN4839:
If all the lines are allocated, the cache controller runs the line eviction process, where a line is selected (depending on replacement algorithm) cleaned/invalidated, and reallocated. The data cache and Instruction cache implement a pseudo-random replacement algorithm.
AN4838 is also closely related.
2021-05-21 01:36 PM
Use the By Address variant of Invalidate DCache, lest very bad things happen...
Why? Because it trashes data pending to the stack, among other things, and that's hard to unwind and will cause unpredictable behaviour.
https://www.keil.com/pack/doc/CMSIS/Core/html/group__Dcache__functions__m7.html
2021-05-22 08:20 AM
The functions, which clean/invalidate the whole cache, normally should not be used at all and are almost useless. Typically I-cache can just be enabled and doesn't require any further management. For D-cache a proper management has to follow 3 basic rules:
Yes, even for receive part the invalidation must be done before passing buffers to DMA, because otherwise cache eviction can damage the receive buffers by writing back dirty lines during reception. A cite from AN4839:
If all the lines are allocated, the cache controller runs the line eviction process, where a line is selected (depending on replacement algorithm) cleaned/invalidated, and reallocated. The data cache and Instruction cache implement a pseudo-random replacement algorithm.
AN4838 is also closely related.
2021-05-22 01:38 PM
#ifndef __SCB_DCACHE_LINE_SIZE
#define __SCB_DCACHE_LINE_SIZE 32U
#endif
void flush_cache(bool is_TX, void *ptr, unsigned len)
{
if (!ptr || (len == 0))
__BKPT(0);
// ptr, len may be not cacheline aligned: see impl. of SCB_CleanDCache_by_Addr
// but we require alignment to be sure
if ( len & (__SCB_DCACHE_LINE_SIZE - 1))
__BKPT(0);
if ((uintptr_t)ptr & (__SCB_DCACHE_LINE_SIZE - 1))
__BKPT(0);
if (is_TX) {
SCB_CleanDCache_by_Addr(ptr, len);
} else {
SCB_InvalidateDCache_by_Addr(ptr, len);
}
}
2021-05-23 05:44 AM
Hi All,
thank you for all your input.
I implemented the clean/invalidation by address and on all my hardware (M7 and H7) and things run well.
Great support, thank you.
Edo