cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F7 HAL DMA cache coherence and DTCM RAM differentiation

i23
Associate II
Posted on October 20, 2015 at 18:18

Hello Community!

I would like to know how, where, and on what conditions the DMA safety is ensured in STM32F7 HAL drivers and how DTCM is considered in them.

I've generated a Cube-Project with freeRTOS for SystemsWorkbench and use it as the basis. What struck my eye is that the link-script only has two sections: FLASH and RAM, RAM spanning both DTCM and normal ram blocks.

Now considering a transfer from/into a buffer alloced by freeRTOS's malloc I, as far I see, could land in both DTCM and RAM. Some online resources, e.g. ChibiOS forums, state that in case of SRAM the CortexM7 chaches must be invalidated or flushed for writes/reads accordingly and even the alignment against a cache line may need to be enforced. ChibiOS forum state that using DTCM only is a simple workaround, which according to manual does support DMA transfers.

So, as cache coherence problems may be nearly impossible to diagnose in the future, I'd ask in front: does (and if so - how?) the HAL ensure cache coherence in randomly allocated memory blocks? Do I need to modify the link script to work with DMA and possibly use DTCM more efficiently avoiding DMA collisions? Do I need to force a static buffer allocation instead of malloc?

Also, the refManual states that the DMA access to DTCM is done via a ''specific AHB slave bus''. Do I need to clock anything specific to enable it? (I'm fighting DMA Transfer errors currently and will post the code in an another thread if don't find the issue)

Best regards,

Mav

#ccm #cache-coherence #dtcm
4 REPLIES 4
Nesrine M_O
Lead II
Posted on October 22, 2015 at 17:42

Hi Mav,

“Does (and if so - how?) the HAL ensure cache coherence in randomly allocated memory blocks? Do I need to modify the link script to work with DMA and possibly use DTCM more efficiently avoiding DMA collisions? Do I need to force a static buffer allocation instead of malloc?�?

HAL API doesn’t guarantee data coherency between the core and the DMA. In fact the data coherency is ensured by either:

 

• write-back policy with coherency ensured by software (clean or invalidate D-Cache)

 

• cache enabled with write-through policy

“The refManual states that the DMA access to DTCM is done via a ''specific AHB slave bus''. Do I need to clock anything specific to enable it? (I'm fighting DMA Transfer errors currently and will post the code in an another thread if don't find the issue)�?

There is nothing specific, it is managed by the cortex with STM32 sub-system, and you need just a buffer declared in DTCM RAM.

-Syrine –

i23
Associate II
Posted on October 23, 2015 at 17:24

Thank you, Syrine! I won't enable caches in my application to avoid trouble with HAL.

Posted on May 04, 2018 at 19:50

Invalidate Cache is your friend.  I have found on the H743i that it does not matter if the Cache is Enabled or Disabled.  Setting a buffer with data and then using the DMA HAL to send the buffer contents to the UART will send the wrong data if Invalidate Cache is not called prior to the HAL call.  In fact I tried all combinations of Cache enabled, disabled, Clean Cache and Invalidate Cache and Invalidate is the only thing the worked 100%.  My buffer was in RAM_D1 (0x2400000). 

Posted on May 04, 2018 at 21:06

Could it be an issue with the Write Thru behaviour?

static void MPU_Config(void)

{

  MPU_Region_InitTypeDef MPU_InitStruct;

  /* Disable the MPU */

  HAL_MPU_Disable();

  /* Configure the MPU attributes as WT for SRAM1 */

  MPU_InitStruct.Enable = MPU_REGION_ENABLE;

  MPU_InitStruct.BaseAddress = 0x24000000;

  MPU_InitStruct.Size = MPU_REGION_SIZE_512KB;

  MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;

  MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;

  MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;

  MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;

  MPU_InitStruct.Number = MPU_REGION_NUMBER1;

  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;

  MPU_InitStruct.SubRegionDisable = 0x00;

  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;

  HAL_MPU_ConfigRegion(&MPU_InitStruct);

  /* Enable the MPU */

  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);

}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..