关于NvM作为ServiceSwComponent的案例介绍,请阅读:
本文将关注于NvM作为NvBlockSwComponent是如何工作的。
当NvM作为NvBlockSwComponent时,在RTE这一层会创建RAM块,可以被一个或多个SWC通过NVData接口进行读取或者写入。
同时,NvMBlockUseSyncMechanism需要设置为TRUE,使用显性同步。这些RAM块通过NvM的RAM镜像进行访问。
如果用户仍旧希望使用一个临时的RAM地址,可以继续使用NvM_ReadBlock/NvM_WriteBlock接口。

使用这种方案,最大的好处就是一个RAM块可以共享给多个SWC或BSW使用,降低资源的消耗。也不需要消耗额外的buffer。
同时,也可以基于NVData写入频率的不同设定不同的写入策略,RTE会负责处理这些写入操作。RTE也会负责NVData访问时的一致性。
这种场景下,NvBlock能提供的接口有:

使用Rte显性S/R通信
在这个场合中,Rte_Write/Rte_Read/Rte_DRead被用来更新或读取RAM块,或是RAM块中的某一个元素。
Rte并不会自发地触发NvM的写入操作,用户需要在更新RAM块数据后,显性地进行请求:

如果dirtyFlagSupport设置为true,且NvBlockNeeds.storeCyclic也设置为true,那么Rte会周期性地触发写入操作:

如果NvBlockNeeds.storeAtShutdown也设置为true,那么在SWC更新了RTE中RAM块的数据时,RTE会调用NvM_SetRamBlockStatus,告知NvM此数据已被修改,这样的话,在系统关闭调用NvM_WriteAll时,修改过的数据也会更新到NV中。

如果是NvBlockNeeds.storeImmediate设置的为true,那么SWC在请求更新RTE里的RAM数据后,RTE会立即向NvM请求写入操作。
这个时候有两种选择,如果为NvBlockNeeds添加过DataReceivedEvent,且DataReceivedEvent映射到某一个task,那么在SWC请求RTE更新RAM数据时,RTE会设置事件以激活任务,来调用NvM_WriteBlock。
如果没有添加过DataReceivedEvent,那么在SWC请求RTE更新RAM数据时,RTE会在当前上下文中请求NvM写入操作(如下图)。

使用Rte隐性S/R通信
这种情况下,会使用到Rte_IWrite/Rte_IWriteRef/Rte_IRead接口。
这些接口会缓存待写入的数据,直到请求服务的runnable结束。然后,RTE会使用最后写入的数据更新到RTE中的RAM块中。
默认地,RTE仍旧不会自发地请求NvM操作,用户需要进行请求。

dirtyFlagSupport、NvBlockNeeds.storeCyclic、NvBlockNeeds.storeAtShutdown、NvBlockNeeds.storeImmediate设置为true的情况,执行过程与上述的显性S/R逻辑相同,这里不再赘述。