I'm trying to make one region of SRAM non cacheable for DMA buffers. But what I have found is that when I do that, the first atomic operation bus faults (eg RTOS mutex).
Here's an example where I made all of SRAM normal memory non cacheable (TEX=1 B=0 C=0 S=1) for testing:
// all SRAM non cacheable
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = 0x20000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_1MB;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
It does not matter what the atomic operation is; it faults on the `ldrex` instruction. I've checked alignment and the access is on a 32 bit boundary. Actual memory location can be in DTCM or SRAM1 and it will fault in both.
If I change the MPU region to 'normal memory non cacheable non sharable (TEX=1 B=0 C=0 S=0)' then it will not fault but it appears that caching is still enabled for that memory region.
The manual states:" LDREX and STREX operations must be performed only on memory with the Normal memory attribute. "
Check also the notes on "shareable" attribute!
My understanding is that both (TEX=1 B=0 C=0 S=1) and (TEX=1 B=0 C=0 S=0) are normal memory types.
I'll look into this further as the bus fault would indicate that I am wrong.
Robert Grey said:Actual memory location can be in DTCM
DMA will not work with DTCM!
DMA works just fine using DTCM memory via the AHBS bus. However I have the SRAM divided into DTCM and SRAM1/SRAM2 memory and have placed the DMA buffers in SRAM1/SRAM2. My problem is that I cannot get the MPU to disable caching on that memory.
Which chip is it? Maybe it helps to clear thing. M7 is not M7.
Sounds like an STM chip. Anyway, I do set the DEVICE attribute for non-cacheable regions. And of course keep this region at minimum size for the DMA only.
Robert Grey said:It does not matter what the atomic operation is; it faults on the `ldrex` instruction.
Ok, I can confirm the behavior for an STM32H7.
On an i.MXRT1064 (also CM7) it works with shared attribute set. But this chip is designed for multi-core (1171 has CM7 and CM4). Which might be the difference. Shared attribute makes no sense on STM32H7.
Sadly, this also seems to be a problem on the dual-core STM32H755. Mapping an SRAM bank as Normal, Noncacheable, Shareable memory causes LDREX to bus fault on the Cortex-M7 core. Interestingly, LDREX does _not_ fault on the Cortex-M4 core.
From https://www.st.com/resource/en/application_note/dm00272912-managing-memory-protection-unit-in-stm32-mcus-stmicroelectronics.pdf (emphasis mine):
The S field is for a shareable memory region: the memory system provides data synchronization between bus masters in a system with multiple bus masters, for example, a processor with a DMA controller. A strongly-ordered memory is always shareable. If multiple bus masters can access a non-shareable memory region, the software must ensure the data coherency between the bus masters. The STM32F7 Series and STM32H7 Series do not support hardware coherency. The S field is equivalent to non-cacheable memory.