【Vitis】由缓存导致DMA读写数据不一致的解决办法

参考博客:

  1. https://blog.csdn.net/weixin_38712697/article/details/99693531
  2. 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开发,对知识的理解可能会有错误,欢迎大佬批评指正。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wjh776a68

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值