用DMA进行数据传输时,需要解决DCache(Data Cache)和DDR Memory之间的数据一致性问题。
PS通过DMA向PL写数据
1)调用:Xil_DCacheFlushRange(INTPTR adr, u32 len);
2)DMA写PL:XAXIDMA_DMA_TO_DEVICE
PS通过DMA从PL读数据
1)DMA读PL:XAXIDMA_DEVICE_TO_DMA
2)调用:Xil_DCacheInvalidateRange(INTPTR adr, u32 len)
注意事项:
调用Xil_DCacheInvalidateRange(INTPTR adr, u32 len)时,地址adr和长度len必须和CacheLine的长度对齐(A9的CacheLine=32字节,A53的是64字节)。
如果首地址/尾地址没有和CacheLine对齐,数据会出错,原因是:Xil_DCacheInvalidateRange函数内部会先把未对齐的首地址/尾地址对应的CacheLine先Flush到DDR里,导致DDR里的数据被覆盖,出错。
地址adr对齐的示例代码如下:
const u32 CACHE_LINE = 64U;
u32 adr = (u32)malloc(DMA_LENGTH + 2*CACHE_LINE);
//对齐CACHE_LINE
adr += CACHE_LINE;
adr &= ~(CACHE_LINE - 1U);
g_txDma_mgr.orig_ptr =(u8*) adr;
长度len对齐的示例代码如下:
//从DDR更新DCache
if(g_tcp_mgr.total_byte_num % CACHE_LINE>0){ dcacheInvalidLen = (g_tcp_mgr.total_byte_num / CACHE_LINE + 1)*CACHE_LINE; }
else{ dcacheInvalidLen = (g_tcp_mgr.total_byte_num ; }
Xil_DCacheInvalidateRange((INTPTR)g_rxDma_mgr.orig_ptr, dcacheInvalidLen );
参考
[1].xil_cache.c
网友评论