嵌入式开发:使能Cached功能,导致数据一致性破坏

发布于 2023-10-30 11:00
浏览
0收藏

工程开发中,为了提高CPU取指令和取数据的效率,往往会使能Cached功能。Cache,是一种缓存机制,它位于CPU和和主内存(Main Memory)之间,为CPU和主内存之间的读/写操作提供一段缓冲区,如下所示:

嵌入式开发:使能Cached功能,导致数据一致性破坏 -汽车开发者社区

Cache实质是一块高速RAM区,可以使得指令操作或者数据操作在更少的Cycle内完成。结合工程问题,本文主要讨论以下几点:

1. Cached和No Cached的区别

2. 如何使能Cached

3. Cached使能,导致的工程问题

提示:基于tc3xx讨论

1、Cached和No Cached的区别

在芯片手册中,PFlash(tc397,16MByte)对应了两个Segment:Segment 8和Segment A,两者本质上是一块物理内存,因为访问方式不同,所以,同一块物理内存区被映射到了两个不同的Segment,如下所示:

嵌入式开发:使能Cached功能,导致数据一致性破坏 -汽车开发者社区

CPU使用Cached和No Cached地址访问物理内存,示意如下所示:

嵌入式开发:使能Cached功能,导致数据一致性破坏 -汽车开发者社区

举例:CPU需要读取Argu参数的值,NoCached方式访问时,使用Segment A对应的地址(eg:0xA00E0000),此方式直接从主内存读取数据;Cached方式访问时,使用Segment 8对应的地址(eg:0x800E0000),此方式访问时,CPU会先去Cached对应的缓存区读取(一块RAM区),如果缓存区内没有,再去主内存去读取。NoCached、Cached方式读取Argu参数,示意如下:

嵌入式开发:使能Cached功能,导致数据一致性破坏 -汽车开发者社区

2、Cached使能

Cached功能又细分为PCached和DCached,两者相互独立,可以分别使能。在多核系统中,每个核均可单独使能Cached,Cached的使能一般在启动文件中操作,对于PCached和DCached的使能,每个核均有对应的操作寄存器。


(一)DCON0寄存器使能DCached


默认情况下,DCON0.DCBYP = 1,即:不使能DCached,如下所示:

嵌入式开发:使能Cached功能,导致数据一致性破坏 -汽车开发者社区

(二)PCON0寄存器使能PCached


默认情况下,PCON0.PCBYP = 1,即:不使能PCached,如下所示:

嵌入式开发:使能Cached功能,导致数据一致性破坏 -汽车开发者社区

3、工程问题:使能Cached,导致数据不一致

Cached使能以后,如果不注意数据一致性保护,就会导致工程Bug。举一个工程问题:软件(Application)更新,复位ECU后,使用$31 01检查软件兼容性,校验不过


(一)问题分析


Bootloader和Application中均使能了PCached、DCached功能,且软件兼容性参数存放在PFlash中。程序更新后,需要比对软件兼容性,只有参数与新存入PFlash中的参数一致,更新的Application才能生效。

Step1:更新Application前,读取指定地址(0x800E0000)的软件兼容性参数,使用Cached方式读取,如下所示:

DataArr = *((uint32*)0x800E0000);

此时,软件兼容性参数为0x55555555,如下所示:

嵌入式开发:使能Cached功能,导致数据一致性破坏 -汽车开发者社区

Step2:更新Application程序,同时更新指定地址(0x800E0000)处的软件兼容性参数为0xAAAAAAAA,如下所示:

writeProgramFlash(0xAAAAAAAA);

Appliation程序更新,软件兼容性参数地址0xA00E0000(NoCached)和地址0x800E0000(Cached)均更新为指定值0xAAAAAAAA,如下所示:

嵌入式开发:使能Cached功能,导致数据一致性破坏 -汽车开发者社区

再次读取指定地址(0x800E0000)的软件兼容性参数,使用Cached方式读取,如下所示:

DataArr = *((uint32*)0x800E0000);

读取软件兼容性参数,依然是0x55555555,并不是更新后的0xAAAAAAAA,这就导致了数据一致性被破坏,即:缓存区与主内存区数据不一致。当更新主内存的数据以后,因为缓存区数据依然存在,而当CPU再次访问时,在缓存区找到了该参数(hit,命中),优先使用了缓存区中的0x55555555,而不是主内存区的0xAAAAAAAA。

嵌入式开发:使能Cached功能,导致数据一致性破坏 -汽车开发者社区

(二)解决策略


既然缓存区和主内存数据不一致,解决的根本就是想办法使得两者数据一致,怎么做呢?:方法有多种,比如:

1. 不使用Cached功能(不推荐),仅NoCached方式访问;

2. 使用Cached访问时,如果数据有更新,先将缓存区数据设置无效,让CPU再次去主内存读取一次数据放到缓存区。

避免数据不一致操作,不同的芯片指令可能有所不同,本文讨论CACHEI.*指令,主要目的是将参数对应的Cache Line数据设置无效,重新从主内存区加载。

Step1:更新Application前,读取指定地址(0x800E0000)的软件兼容性参数,使用Cached方式读取,如下所示:

嵌入式开发:使能Cached功能,导致数据一致性破坏 -汽车开发者社区

读取参数为0x55555555。

Step2:更新Application程序,同时更新指定地址(0x800E0000)处的软件兼容性参数为0xAAAAAAAA,如下所示:

writeProgramFlash(0xAAAAAAAA);

Step3:将0x800E0000地址设置无效,重新从主内存区加载对应的参数值到缓存区,具体操作如下:

{
uint8 *localCachedPtr = ((uint8*)0x800E0000);   
Ifx__Cacheawi(localCachedPtr);}

再次读取0x800E0000值,如下所示:

嵌入式开发:使能Cached功能,导致数据一致性破坏 -汽车开发者社区

如上,可以看出,读出的数据为预期值,即:缓存区和主内存区值一致。


文章转载自公众号:开心果 Need Car

分类
收藏
回复
举报
回复
相关推荐