2022-08-04 08:06 AM
Using the linker script - How would I assign an area of AXI SRAM1 that is not cacheable by DCache? I am currently having problems with DMA transfers to the PWM peripheral when DCache is enabled (I think this is because I am sending 8bits to the HAL_TIM_PWM_Start_DMA and DCache likes aligned WORDS (I believe...)). I have tried Invalidating the cache - which doesn't yield any positive results and it seems the DMA/Peripheral cannot address the DTCRAM banks (AHB_SRAM 1 + ") which are uncacheable.
Is it possible to assign an area of AXI RAM, using the linker script and/or the startup script, to be uncachable?
A good starting point seems to be suggested by another ARM mcu manufacturer ...
but are there uncachable areas of the AXI RAM?
The same could be asked of non cacheable FLASH as looking at the STM32H7B block diagram I see that it is connected to the same AXI Bus Matrix
In addition I may have a look at the MPU but it seems incredible hard to configure...
Any advice is most welcome...
2022-08-04 08:42 AM
I've tried the MPU with the following
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = 0x240C00000;
MPU_InitStruct.Size = MPU_REGION_SIZE_256KB;
MPU_InitStruct.SubRegionDisable = 0x87;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
and the results are somewhat improved but how to you allocated variables to specific memory addresses?
2022-08-04 09:00 AM
If you're sending stuff (ie MCU->MEM->DMA->TIM), Invalidating the cache is entirely the WRONG strategy. CLEAN == FLUSH, INVALIDATE == NUKE FROM ORBIT, the latter will do so much collateral damage, it'll burn what's in the write buffers, and whatever is destined for memory.
>>and the results are somewhat improved but how to you allocated variables to specific memory addresses?
You attribute variables specifying a named section they dwell in.The linker is then responsible for honouring this.
For things you don't even tell the linker about, you can just use pointers. Complex things, structures, with pointers.
2022-08-04 09:13 AM
In addition to the MPU settings is this a step in the right direction?>??
RAM (xrw) : ORIGIN = 0x24000000, LENGTH = 768K
RAM_NOCACHE (xrw) : ORIGIN = 0x240C0000, LENGTH = 256K
.DATA_RAM_NOCACHE (NOLOAD) :
{
} >RAM_NOCACHE
and
buff[SIZE] __attribute__((section (".DATA_RAM_NOCACHE"))) ;
2022-08-04 09:50 AM
Would I be right in thinking that the above comment does not work for pointers i.e the linker needs to specify something like *(.DATA_RAM_NOCACHE*) . It's just that I'm getting random silly addresses when storing pointers to this area of RAM. If that is correct would you also need some initialization in the startup script?
2022-08-04 10:07 AM
I think I've done it!!!
.DATA_RAM_NOCACHE :
{ . = ALIGN(4);
_snocachedata = .;
*(.DATA_RAM_NOCACHE)
*(.DATA_RAM_NOCACHE*)
. = ALIGN(4);
_enocachedata = .;
} >RAM_NOCACHE
_sinocachedata = LOADADDR(.DATA_RAM_NOCACHE);
in the linker
.word _sinocachedata
/* start address for the .nocache section. defined in linker script */
.word _snocachedata
/* end address for the .nocache section. defined in linker script */
.word _enocachedata
ldr r0, =_snocachedata
ldr r1, =_enocachedata
ldr r2, =_sinocachedata
movs r3, #0
b LoopCopyDataInit
This in conjunction with the MPU seems to yield the expected result 🙂
2022-08-04 10:16 AM
A new problem however. The DMA will have to acquire data from FLASH in the final solution... Can MPU and the linker start up setup be used for this area?
Disregard this - the pointer to the const array was the important part that needed to be kept out of cache. The data itself seems to fine left as is