cancel
Showing results for 
Search instead for 
Did you mean: 

Confused about DMA and Cache on STM32 H7 devices.

Bluemelony
Associate II

While I was looking for H7 DMA data,

I saw the article below that DMA is not working on the H7 device.

https://community.st.com/s/article/FAQ-DMA-is-not-working-on-STM32H7-devices

Solution 1 from that article is shown below.

-----------------------------------------------------------------------------------------------------------------------------

Solution example 1: Simple placement of all memory to D1 domain

"D-Cache must be disabled globally for this solution to work."

GCC (Atollic TrueStudio/System Workbench for STM32/Eclipse)

"Replace DTCMRAM with RAM_D1" for section placement in linkerscript (.ld file extension). E.g. like this:

.data :

{

... /* Keep same */

} >RAM_D1 AT> FLASH

-----------------------------------------------------------------------------------------------------------------------------

But, "STM32Cube_FW_H7_V1.9.0/NUCLEO-H743ZI/Examples/ADC/ADC_DMA_Transfer"

In the example, DTC MRAM is changed to RAM_D1 (STM32H743ZITx_FLASH.ld),

but the Main.c file is : (Line 58)

/* Enable the CPU Cache */

CPU_CACHE_Enable();

The solution should replace DTC MRAM with RAM_D1 and disable D-Cache globally, but the example does not appear to be the case.

Which one is correct?

1 ACCEPTED SOLUTION

Accepted Solutions
Ons KOOLI
Senior III

Hi @Bluemelony​ ,

When working with DMA for STM32H7 devices, you should pay attention to the memory allocation.

The default memory used by most of ST projects is DTCM which is not accessible by DMA in STM32H7 devices.

So, you should change it to something else which is accessible by DTCM (for example AXI SRAM 0x2400 0000). Please refer to the corresponding reference manual, under System Architecture section.

In most cases this can solve the issue. However sometimes for more advanced applications, the D-Cache can affect the functionality of DMA transfers, since the default cache policy for product SRAMs is normal memory (cacheable). Cache will hold the new data in the internal cache and don't write them to SRAM memory. However, the DMA controller loads the data from SRAM memory and not D-Cache. Same behavior can happen when reading data, as DMA will update buffers in SRAM, and the content of SRAM will not be immediately visible to CPU as CPU will see previously cached data. This will result in data coherency issues.

So if changing memory allocation did not solve the problem, you have to disable the D-Cache. But I think in your case changing memory allocation to AXI SRAM (for example) is enough to solve the issue.

Best Regards,

Ons.

View solution in original post

8 REPLIES 8

What does CPU_CACHE_Enable() do, does it enable data cache?

Isn't the memory portion used for DMA excluded from caching using MPU in that example?

JW

Thank you for your answer!

The CPU_CACHE_Enable() function contents are shown below.

static void CPU_CACHE_Enable(void)

{

 /* Enable I-Cache */

 SCB_EnableICache();

 /* Enable D-Cache */

 SCB_EnableDCache();

}

And in the example, MPU seems to be not used...

However, the ADC buffer is defined as 

#define ADC_CONVERTED_DATA_BUFFER_SIZE  ((uint32_t) 32)  /* Size of array aADCxConvertedData[] */

ALIGN_32BYTES (static uint16_t aADCxConvertedData[ADC_CONVERTED_DATA_BUFFER_SIZE]);

and the ADC callback function is shown below.

void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)

{

 /* Invalidate Data Cache to get the updated content of the SRAM on the first half of the ADC converted data buffer: 32 bytes */

 SCB_InvalidateDCache_by_Addr((uint32_t *) &aADCxConvertedData[0], ADC_CONVERTED_DATA_BUFFER_SIZE);

}

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)

{

  /* Invalidate Data Cache to get the updated content of the SRAM on the second half of the ADC converted data buffer: 32 bytes */

 SCB_InvalidateDCache_by_Addr((uint32_t *) &aADCxConvertedData[ADC_CONVERTED_DATA_BUFFER_SIZE/2], ADC_CONVERTED_DATA_BUFFER_SIZE);

}

I think, this example use ADC DMA with ICache, DCache and Cache maintenance functions.

but I don't understand why the .ld file changed DTCM_RAM (0x20000000) to RAM_D1 (0x24000000) even when using Cache...

In 'H7, DTCM is not accessible from the DMA1/DMA2.

JW

Um...If I use H7 device DMA, is it right to do this?

1. Enable ICache and DCache.

2. Data RAM region in linker file(.Id) Change from 0x20000000 (DTCM_RAM) to 0x24000000 (RAM_D1).

3. Define the DMA buffer as ALIGN_32BYTES.

4. Use DMA Cache maintenance functions. (SCB_InvalidateDCache_by_Addr or SCB_CleanDCache_by_Addr)

I don't use the 'H7, just follow what's written in the article you gave link to.

JW

TDK
Guru

> Um...If I use H7 device DMA, is it right to do this?

Yes, that's one possibility for how to handle caching.

If you feel a post has answered your question, please click "Accept as Solution".
Ons KOOLI
Senior III

Hi @Bluemelony​ ,

When working with DMA for STM32H7 devices, you should pay attention to the memory allocation.

The default memory used by most of ST projects is DTCM which is not accessible by DMA in STM32H7 devices.

So, you should change it to something else which is accessible by DTCM (for example AXI SRAM 0x2400 0000). Please refer to the corresponding reference manual, under System Architecture section.

In most cases this can solve the issue. However sometimes for more advanced applications, the D-Cache can affect the functionality of DMA transfers, since the default cache policy for product SRAMs is normal memory (cacheable). Cache will hold the new data in the internal cache and don't write them to SRAM memory. However, the DMA controller loads the data from SRAM memory and not D-Cache. Same behavior can happen when reading data, as DMA will update buffers in SRAM, and the content of SRAM will not be immediately visible to CPU as CPU will see previously cached data. This will result in data coherency issues.

So if changing memory allocation did not solve the problem, you have to disable the D-Cache. But I think in your case changing memory allocation to AXI SRAM (for example) is enough to solve the issue.

Best Regards,

Ons.

Thank you for your kind answer ! !