DMA 和缓存
当使用 DMA 在内存之间或者内存和外设之间传输数据,如果此时 Cache 也正常启用,需要注意 Cache 和内存数据不一致的问题。
DMA TX
当 DMA 的源端是 Memory,需要发送数据时,一般流程如下:
申请发送缓冲区,需要确保起始地址和大小都与 Cache Line 对齐。
CPU 将数据写入 Memory 缓冲区。
调用
DCache_Clean()函数清理数据缓存配置 DMA 发送参数
DMA 启动传送
DMA RX
CPU 分配接收缓冲区
执行
DCache_Clean()确保接收缓冲区处于 clean 状态(如果接收缓冲区处于 clean 状态,可跳过此步骤)小心
此步骤执行的原因是:
对于 Cortex-A32,如果 Cache 中的接收缓冲区处于 dirty 状态,执行第 5 步
DCache_Invalidate()将同时执行 clean 和 invalidate 操作,可能会导致意外写入行为。如果 Cache 中的接收缓冲区处于 dirty 状态,当 CPU 的 D-Cache 满了,CPU 可能会将接收缓冲区中的脏数据写回内存,覆盖 DMA 已经写入的内容。
配置 DMA Rx 参数
配置并使能 DMA Rx 中断处理函数
执行
DCache_Invalidate()作废 Cache 中对应的数据,确保 Cache 没有残留旧的接收缓冲区数据。
小心
此步骤必须执行,原因如下:
对于具有自动数据预取功能的 CPU(如 Cortex-A32 和 DSP),当 CPU 读取接收缓冲区相邻地址的内容时,CPU 会在后台执行行填充操作,自动将接收缓冲区的旧值重新加载到 Cache 中。
防止 CPU 在 DMA 处理期间将旧值读入 Cache。
CPU 读取接收缓冲区(DMA Rx 返回的值)
备注
将缓冲区地址与 Cache Line 行对齐将减少 Cache 与内存数据不一致的问题。