在上文中,我们了解到了NvData处理的时候有两种同步机制,分别是隐性同步和显性同步。
本文集中研究两种同步机制的区别。
配置工具中的选项
以EB Tresos为例,我们在NV Block的配置选项中,能找到开启/关闭显性同步机制的开关,默认情况下未开启,为隐隐性同步模式。
隐性同步
NvM默认使用的就是隐性同步,如果有多个应用使用同一块RAM区域,那么这些应用之间需要自行保证进行Nvm操作过程中还有对RAM区域的访问。
以demo为例,我们为SWC配置了一个NV Block,并且对应的Ram为Demo_CyclicCounter_Ram_Block。
由于通过设计软件设计了此Nvm service及访问连接(此文不详细展开),我们在Rte中能够看到生成的接口:
#define Rte_Pim_PimCounterValue() Rte_Inst_SWC_CyclicCounter->Pim_PimCounterValue
----------------------------------------------------------------------------------
CONSTP2CONST(Rte_CDS_SWC_CyclicCounter, RTE_CONST, RTE_CONST) Rte_Inst_SWC_CyclicCounter = &Rte_Instance_SWC_CyclicCounter;
----------------------------------------------------------------------------------
CONST(Rte_CDS_SWC_CyclicCounter, RTE_CONST) Rte_Instance_SWC_CyclicCounter =
{
&Demo_CyclicCounter_Ram_Block
};
所以我们可以在应用中修改RAM区域的数值:
(*Rte_Pim_PimCounterValue()) = counterValue;
然后设置修改状态:
(void) Rte_Call_PS_PersistentCounterValue_SetRamBlockStatus(TRUE);
这样,比如下电前,NvM WriteAll的时候就会把这个数值写到对应的NV Block里。或者SWC直接去调用Write Block也行。
启动时同理,Nvm先读到Ram里,然后SWC调用Rte_Pim_PimCounterValue获取从Nvm里读取出来的值。
显性同步
显性同步机制相比较于隐性同步机制,有一个好处是,Nvm任务执行期间不限制RAM块数据的使用。根据配置的不同,由于Nvm需要预备内部空间作为镜像,可能会不同程度地增加RAM的使用量。
选择显性同步时,数据在镜像区域和RAM块之间地拷贝,都需要基于用户自定义的回调函数进行。
比如Dem需要使用的Default Data Block,在Nvm里设置了显性同步,下电执行NvM_WriteAll期间在其回调函数Dem_NvMWriteCopyEventStatusBlock中,Dem将数据拷贝到Nvm的镜像当中。
