• 嵌入式开发中Cache问题的解决方法


    关注+星标公众,及时获取更多技术分享~ 

     作者 | 冰茶奥利奥

    微信公众号 | 嵌入式电子创客街 


    最近在使用一款Cortex-A7芯片时,出现了一个让人比较困惑的问题。ARM和FPGA通过DDR3进行数据通信,FPGA会把数据定时存放进DDR3里面,然后ARM通过读取DDR3获取数据。

    我们知道,在ARM架构体系下,一切皆地址。一片512MB的DDR3对应的不过也是一串长度为512M字节的地址。比如我的板子上,DDR3分配的地址就是从0x00100000—>0x1FFFFFFF,大小为512M。

    我们知道,CPU和外设之间有多级的缓存结构,其模型就如同金字塔一般,如下图所示,最顶层的就是CPU的寄存器了,越往下存储量越大同时读写更慢。我们的DDR在L4那一层,属于DRAM主存。

    当然,在ARMv7架构里一般只有两级高速缓存,即L1和L2。

    存储器层次结构

    在一般的计算机系统中,为了实现更快的访问速度,通常会采取这种数据缓存的方式。当然,像stm32这种Cortex-M3内核的芯片,CPU和外设总线之间是没有任何缓存的,这也是为什么stm32开发时候从来不需要考虑这种问题,这样设计的好处当然是使程序的行为更可预测,但是缺点就是速度被大大限制了。

     CPU通过高速缓存更快的工作

    话说回来,CPU和FPGA都在独立运行,CPU通过DDR控制器来对DDR存储器进行访问,为了加速,常常将一些数据缓存(Cache),而且不是针对一个数据缓存,而是针对一批(有些芯片称为一行,即Line,一行长度为32)。这样好处很明显,下一次访问速度会加快;但坏处也很明显,就是Cache里的数据如果发生了改变,不能迅速反映到DDR3实际数据中,反之亦然。因此,当FPGA通过DMA修改了DDR3数据时,CPU可能还不知道发生了些什么,拿到的数据仍然是Cache中的没有改过的数据。

    在裸机开发时,规避Cache最简单的方法就是禁用Cache。

    DCacheDisable(void);

    这样操作后,CPU将直接访问DDR内存,读写都是直接的。由于FPGA非常频繁的再往DDR3里面写数,就会不断的触发CPU去刷新映射的数据。这样显然会降低CPU性能,但简化了数据传输操作,属于极端的方法。

    另外一种操作要多加一道手续,通常ARM芯片的驱动里有Cache FlushCache Invalidate的操作。从字面理解,Flush就是把Cache里的数据流放出去,清空Cache,也就是将Cache的内容推到DDR中去;而Cache Invalidate表示当场宣布Cache里的内容无效,需要从DDR中重新加载,即把数据从DDR中拉到Cache中来。理解了这个原理,在编程的时候心里就非常有底气了!

    每当我们的程序想要从DDR里面获取数据时,只需要调用CacheInvalidate就可以使CPU立即获取一次最新的DDR数据。

    反之,如果我们的程序想往DDR里面送数据时,只需要调用CacheFlush就可以使CPU立即将数据送至DDR。


    如果您觉得这篇文章帮到了你,请点赞或者留下您的评论,您的鼓励是我前进的动力~

    关注博主公众号 “嵌入式电子创客街” 获取更多及时技术分享~

    关注+星标公众,及时获取更多技术分享~ 

  • 相关阅读:
    凸优化问题定义及其凸函数、凸集、仿射函数相关概念和定义
    通过硬件计数器,将性能提升3倍之旅
    洛谷 P2183 [国家集训队]礼物)(扩展卢卡斯定理)
    QT5槽函数的重载问题
    mysql修改数据库名称
    redis 配置与优化
    Python版A股选股软件源代码,选股系统源代码,实现多种选股策略
    C++ 多线程 condition变量
    Go 语言图片处理简明教程
    Spring Boot系列之条件注解
  • 原文地址:https://blog.csdn.net/shizhibuyi1234/article/details/125600653