参考博客:
-
https://blog.csdn.net/weixin_38712697/article/details/99693531
-
https://blog.csdn.net/qq_40268672/article/details/117953102
问题描述:
利用vitis进行C程序裸机开发时,使用vitis自带的内存查看器可以方便地查看变量的值,在编写一个PL向PS进行DMA数据传输的工程时,经常会出现PL通过DMA传输给PS的数据与PS读取到的数据不一致的异常情况。
产生原因:
经过查阅
资料
,CPU和vitis的内存查看器读取的是缓存中对应地址的数据,而DMA传输数据是写入DDR中,数据在这几者之间的传递关系为:
CPU/内存查看器-缓存-DDR-DMA
由于DMA改写DDR中的数据CPU并不知情,因此对应该DDR地址的缓存数据不会更新,最终导致CPU读取的数据与DMA写入的数据不一致。
解决办法
想要使CPU读取到正确的数据,需要代码中手动添加强制更新缓存的代码,文章开头提供的两篇参考博客中就有提供详细的代码。
下面是我在使用102开发板时PS能够正确读取到PL发来的数据的代码,主要在米联客代码的基础上修改而来,支持多次DMA传输时PS读取到数据的准确性。
void dma_pl2ps(float *baseaddr, int length) //pl to ps
{
TxDone = 0;
RxDone = 0;
Error = 0;
Status = 2;
Xil_DCacheFlushRange((u32)RxBufferPtr, length); //强制将RxBufferPtr在缓存中的数据刷入DDR
Status = XAxiDma_SimpleTransfer(&AxiDma, (u32) RxBufferPtr,
(u32)length, XAXIDMA_DEVICE_TO_DMA);
while (Status == 2);
Xil_DCacheInvalidateRange((u32)RxBufferPtr, length);
Xil_DCacheFlushRange((u32)RxBufferPtr, length); //强制RxBufferPtr的缓存失效,将DDR中的数据写入缓存
TxDone = 0;
RxDone = 0;
for (i = 0; i < length / 4; i++) {
*(baseaddr + i) = *((float*)RxBufferPtr + i); //baseaddr将读取到pl发来的正确的数据,并可在内存查看器中显示
}
DMA_DisableIntrSystem(&Intc, TX_INTR_ID ,RX_INTR_ID);
}
由于本人刚刚接触ps开发,对知识的理解可能会有错误,欢迎大佬批评指正。
版权声明:本文为qq_45434284原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。