文章目录
- 前言
- 一、cache是什么玩意儿?
- 二、解决方法
- 1.Xil_DCacheInvalidateRange函数
- 2.未刷新前的问题
- 3.带刷新后的效果
- 总结
前言
也是移植过程中遇到的一个问题,尝试了一些解决方案,也算是解决了这个问题。
这个问题出现在通过以太网传输分辨率为1280*720,帧率为30Fps的图像过程中。在初始化的时候,初始了Xil_DCacheDisable(void)这个函数,相当于直接用CPU去读数据不经过Cache,直接访问PS端的DDR3,初始化了以后在图像传输的过程中会出现帧率突然下降到原先一半的问题,然后又恢复正常。大概猜到了问题应该是在CPU直接读取DDR,速率受到限制导致的。后面把这个注释了以后,视频倒是能够正常显示了,但如果运动过快,屏幕就会出现白色的划痕,画面呈现撕裂的感觉。后面怀疑是还是cache的问题,后面加入了一个刷新cache的函数。终于算解决了这个问题。
一、cache是什么玩意儿?
这个网上也有说,这个问题也是比较普遍的问题,专业名词:cache一致性问题。按照我的理解就是,我们Zynq的PS端有双核CPU,这个速度是比DDR3写入数据的速度要快的。为了解决CPU读取和DDR写入这个过程中速度不一致的问题,就需要一个中间商,用来协调这个速度不一致的问题,这个中间商就是cache。
通过这个cache,把DDR中一批次的数据缓存到这个里面,那么通过cpu去读取的时候他就能对我们去访问这一批次的数据进行加速,相当于提高了CPU的利用率,使得其两者之间能够更加高效的通信,但这玩意儿也随之带来的影响是:当你CPU需要对大量数据进行读取的时候,DDR3那边的数据已经通过AXI总线写入了数据,但此刻还没有被加载到cache上面,因此你通过CPU去读取cache上面的数据可能就是之前的老数据,影响到视频的显示和输出。同样,如果你通过CPU将数据写入DDR3中,DDR3那边也不能立即收到这个数据。所以我们需要及时的去根据我们的需求及时的释放cache上的数据,或者将DDR3的数据加载到cache上,这样就能解决这个过程中造成的图像撕裂的问题。
二、解决方法
1.Xil_DCacheInvalidateRange函数
这个函数就是将DDR3上某个地址的数据,刷新到cache中,这样我们通过USB或者以太网进行数据传输的时候,当需要传输这一行数据的时候将DDR3中的数据刷新到cache中,这样就能避免撕裂的问题。
如下面的代码所示。wr_index_gray是我们读取帧缓存号,根据当前的帧缓存号从而确定我们要写入数据的地址。tx_addr就是根据我们不同的帧缓存号赋值得出的图像传输地址。pkg_size为一行图像大小,值为1280。pkg_num为总行数,在此处为720,pkg_cnt代表我们当前的行数。通过xil_DCachelnvalidateRange函数,tx_addr为刷新的基地址,1280为刷新的数据长度,每刷新一次传输的一行地址,我们就通过这个函数将DDR的数据存入缓存中。
if(wr_index_gray>1)
{
tx_addr = tx_base_addr+(wr_index_gray-2)*pkg_size*pkg_num+pkg_size*pkg_cnt;
}
else
{
tx_addr = tx_base_addr+2*pkg_size*pkg_num+pkg_size*pkg_cnt;
}
Xil_DCacheInvalidateRange(tx_addr & 0xffffffc0,1280);
2.未刷新前的问题
3.带刷新后的效果
总结
今天的牛肉+豆腐拌饭,味道非常的巴适,每次有豆腐的时候,饭总是不够吃,吃饭的时候还是得带点拌饭的东西,不然吃起来牛肉干巴巴的。