DMA and Cache
When using DMA to transfer data between memory regions or between memory and peripherals, if the cache is also enabled, attention must be paid to the problem of cache and memory data inconsistency.
DMA TX
When the DMA source is memory and you need to send data, the general process is as follows:
Allocate a transmission buffer, ensuring that the starting address and size are aligned with the cache line.
The CPU writes data into the memory buffer.
Call the
DCache_Clean()function to clean the data cache.Configure DMA transmission parameters.
Start DMA transfer.
DMA RX
The CPU allocates a receive buffer.
Execute
DCache_Clean()to ensure the receive buffer is in a clean state (if the receive buffer is already clean, this step can be skipped).Caution
The reason for this step is:
For Cortex-A32, if the receive buffer in the cache is in a dirty state, executing step 5
DCache_Invalidate()will perform both clean and invalidate operations, which may lead to unexpected write actions.If the receive buffer in the cache is dirty, when the CPU’s D-Cache is full, the CPU may write back dirty data in the receive buffer to memory, overwriting the content already written by DMA.
Configure DMA Rx parameters.
Configure and enable the DMA Rx interrupt handler.
Execute
DCache_Invalidate()to invalidate cache data and ensure that there is no residual old data from the receive buffer in the cache.
Caution
This step must be performed for the following reasons:
For CPUs with automatic data prefetch (such as Cortex-A32 and DSP), when the CPU reads addresses adjacent to the receive buffer, the CPU will perform a line fill operation in the background and automatically reload the old value of the receive buffer into the cache.
This prevents the CPU from reading old values into the cache during DMA processing.
The CPU reads the receive buffer (the value returned by DMA Rx).
Note
Aligning the buffer address with the cache line will reduce the problem of inconsistent cache and memory data.