Zynq中DMA的Cache一致性

用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

你可能感兴趣的:(Zynq中DMA的Cache一致性)