背景

TI6678的MSMC在默认条件下是开启对L1d的缓存的,但是却没有硬件机制维护MSMC的Cache一致性,在这种情况下如果将多核共享变量存放在MSMC中,将会出现多核访问共享变量不一致的问题。在某个项目进行过程中需要使用MSMC存放核间信号量等共享数据供八核使用,经过查阅资料与实验实现了这一功能,故总结如下,仅供参考。(推荐使用方法二)

简单举例

while(1)
{*(unsigned int*)(0x0c000000)=0x1;     //将Flag设置为0x1;*(unsigned int*)(0x0c000000)=0x2;        //将Flag设置为0x2;
}
unsigned int flag=0;
unsigned int *val=(unsigned int*)(0x0c000000);
while(1)
{flag= *val;           //读取Flag值
}

**在MSMC默认开启Cache的条件下,进行上述操作将会出现核1读取到的Flag值与核0写入的Flag值不一致的现象。**原因是核1从共享内存读取Flag的过程中,由于没有维护Cache一致性,L1D中会缓存先前的数据。因此核0向共享内存重新写入Flag后,核1读取将首先从L1D中获取到数据,结果导致两个核读写数据出现不一致。

解决办法

方法1:L1D手动写回与Cache无效

  • 核0操作如下:
while(1)
{*(unsigned int*)(0x0c000000)=0x1;     //将Flag设置为0x1;CACHE_wbInvL1d((void *)(0x0c000000),4,CACHE_WAIT); //写回数据,并无效L1DCache*(unsigned int*)(0x0c000000)=0x2;     //将Flag设置为0x2;CACHE_wbInvL1d((void *)(0x0c000000),4,CACHE_WAIT); //写回数据,并无效L1DCache
}
  • 核1操作如下:
unsigned int flag=0;
unsigned int *val=(unsigned int*)(0x0c000000);
while(1)
{CACHE_invL1d((void *)(0x0c000000),4,CACHE_WAIT);//无效L1DCacheflag= *val;            //读取Flag值
}

​ 按照上述方法,可以实现多核访问共享内存的一致性。但缺点是每次进行读写的过程中都需要进行手动进行数据写回与无效L1DCache的操作,不便于使用。因此,推荐使用第二种办法。

方法二:地址重映射

使用XMC将MSMC重映射到其他地址(如0x20000000),后续通过访问重映射地址(0x20000000)即可访问MSMC内存空间。重映射后即可利用MAR关闭重映射地址(0x20000000)的Cache使能,间接实现关闭MSMC的L1D Cache。细节可参考《TMS320C66x DSP CorePac (sprugw0b).pdf》“7.3.2.2.2 MSMC RAM Aliasing Scenarios”

  • 将MSMC进行重映射并关闭Cache函数示例

    /*
    * Function:Cache_MSMC_initial
    * Description:用于将MSMC进行重映射并关闭Cache
    */
    #include <ti/csl/csl_xmc.h>
    #include <ti/csl/csl_xmcAux.h>#define  MAR_BASE_ADDR          (0x01848000)void Cache_MSMC_initial(Uint32 index,Uint32 bAddr,Uint8 segSize,Uint32 rAddr)
    {CSL_XMC_XMPAXH         mpaxh;      // 存储保护和地址扩展寄存器(H)CSL_XMC_XMPAXL        mpaxl;      // 存储保护和地址扩展寄存器(L)/******************** 地址重映射 *********************/mpaxh.bAddr   = bAddr;             // 基地址(匹配逻辑地址的高位地址)mpaxh.segSize = segSize;            // 重映射区段大小// 设置XMPAXH寄存器. Writes:XMC_XMPAXH_SEGSZ,XMC_XMPAXH_BADDR.CSL_XMC_setXMPAXH (index, &mpaxh);// 设置该区段地址的访问权限mpaxl.ux = 1;mpaxl.uw = 1;mpaxl.ur = 1;mpaxl.sx = 1;mpaxl.sw = 1;mpaxl.sr = 1;mpaxl.rAddr = rAddr;// 设置XMPAXL寄存器.CSL_XMC_setXMPAXL (index, &mpaxl);// 读取XMPAXL寄存器.CSL_XMC_getXMPAXL (index, &mpaxl);/******************** 地址重映射 *********************/*(unsigned int *)(MAR_BASE_ADDR+ 4*(bAddr>>24))= 0x0;      //关闭重映射地址处cache
    }
  • 核0操作如下:

    int main()
    {unsigned int a=0;Cache_initial(); //开启L1D、L1P Cache,关闭L2 CacheCache_MSMC_initial(3,0x20000,21,0x00C000);   //将MSMC重映射到0x20000000后关闭Cachewhile(1){*(unsigned int *)(0x20100000)=0x01;*(unsigned int *)(0x20100000)=0x02;}
    }
  • 核1操作如下:

    int main()
    {unsigned int flag=0;Cache_initial();Cache_MSMC_initial(3,0x20000,21,0x00C000);  //将MSMC重映射到0x20000000后关闭Cacheunsigned int*val=(unsigned int *)(0x20100000);while(1){flag=*val;}
    }
  • 运行的具体过程为:核0先将FLag写为0x1,然后等待在写0x2的语句处,此时核1读取一次Flag。接着核0将Flag写为0x2,然后等待在写0x1的语句处,此时核1再次读取FLag,以此循环读写。在这个过程中,核1均能获取到MSMC中当前的最新数据。

    此时,如果需要将核间信号量或核间消息队列等共享数据存放在MSMC中,只需要将核间信号量或核间消息队列的基地址分配到0x20000000起始的4MB控件即可。

TI6678 MSMC关闭Cache方法总结相关推荐

  1. php gzip 关闭,手动关闭gzip方法(phpwind、discuz和supesite)

    手动关闭gzip方法(phpwind.discuz和supesite) 2017-10-21 04:10:30 1667 0 phpwind论坛系统: databbscacheconfig.php 修 ...

  2. Handler的postDelayed()关闭的方法

    关闭的方法主要使用removeCallbacks,下面举一个demo 说明 使用方法: 1,首先创建一个Handler对象 Handler handler=new Handler(); 2,然后创建一 ...

  3. php 配置 关闭警告,php warning 关闭的方法

    php warning关闭的方法:首先指定error_log文件:然后在php.ini中设置"display_errors = Off"即可. php关闭warning error ...

  4. C++ close()关闭文件方法详解

    <C++ open打开文件>一节中,详细介绍了文件流对象如何调用 open() 成员方法打开指定文件.相对应地,文件流对象还可以主动关闭先前打开的文件,即调用 close() 成员方法. ...

  5. centos关闭php服务,linux(centos)防火墙的开启与关闭的方法

    本篇文章记录一下在linux(centos)系统下的防火墙的开启,关闭的方法.具体有两种方法: 一.执行"setup"命令启动文字模式配置实用程序,在"选择一种工具&qu ...

  6. Linux下清理内存和Cache方法 /proc/sys/vm/drop_caches

    Linux下清理内存和Cache方法 /proc/sys/vm/drop_caches 频繁的文件访问会导致系统的Cache使用量大增 $ free -m total used free shared ...

  7. 细节打满,IO 操作必须手动关闭?关闭流方法是否有顺序?

    点击关注公众号,实用技术文章及时了解 来源:blog.csdn.net/maxwell_nc/article/ details/49151005 前几天看了一篇文章,自己动手试了下,发现有些不一样结论 ...

  8. 远程计算机关闭了怎么办,怎么远程关闭电脑 远程关闭电脑方法【详细步骤】...

    如果你有多台电脑,不管用什么操作系统,都可以远程关闭它们.下面我就来为大家介绍一下远程关闭电脑方法,一起来看看. 方法1 启用远程注册表服务(Windows) 1.打开要远程关闭的电脑上的" ...

  9. C#—Dev XtraTabControl操作总结如动态增加Tab和关闭选项卡方法等

    1:显示行号 找到gridview属性 点击事件 CustomDrawRowIndicator private void gridView1_CustomDrawRowIndicator(object ...

最新文章

  1. RxJava 源码解析之观察者模式
  2. Linux 忘记root密码(记录)
  3. 爱默生E系列服务器机柜托盘,艾默生通信电源PS48300-3B/1800 一体化室内机柜
  4. 修改类名后依旧按照原先的类名进行加载
  5. 基于JAVA+Servlet+JSP+MYSQL的图书销售管理系统
  6. Session重点整理
  7. linux whois 命令 详解
  8. 计算机音乐狂浪乐谱,当代歌曲 - 听海(流行歌曲 简谱)
  9. win7降低屏幕亮度_win7亮度调节不见了怎么办
  10. 总资产周转率、资产负债率、销售净利率、资产收益率、净资产利润率、劳动生产率、人均利润率
  11. 有效年利率和年化百分比利率
  12. 命令可以在linux的安全系统中,什么命令可以在linux的安全系统中完成文件向磁带备份的工作...
  13. Unity官方案例噩梦射手开发总结<一> 角色的攻击功能实现
  14. JAVA修炼之路的开启
  15. 苹果数据泄漏:内鬼频出,这是库克的错吗?
  16. BIOS功能调用表格
  17. 5/17/2015 今週日本語勉強の纏め
  18. HTML中然后设置前景色,理解CSS前景色和透明度
  19. ISDN PRI协议之第三层协议Q.931
  20. 【02】Java进阶:13-IO资源的处理、属性集、缓冲流、转换流、序列化、打印流、装饰设计模式、commons-io工具包

热门文章

  1. react--无状态组件和有状态组件
  2. 夜莺(Flashcat)V6监控(一):介绍及其部署
  3. 如何在使用pdfFactory Pro生成PDF时自动创建目录书签
  4. 计算机 标量,什么是标量机?标量、向量、张量的区别
  5. Java内功修炼系列一责任链模式
  6. 路侧停车系统是停车缺口解决方案之一
  7. 文本相似度计算(切词、生成词向量,使用余弦相似度计算)
  8. 推荐 6 个 GitHub 开源项目
  9. NOTE-1-基础笔记: FOV视场角
  10. Linux 7配置Proxy Server