本文根据AUTOSAR4.4(Classic Platform)(https://www.autosar.org/standards/classic-platform/classic-platform-440/)标准中的 :
AUTOSAR_EXP_NVDataHandling.pdf
文章整理。仅为个人理解,不当之处,还请指正,感谢!
目录
1 Acronyms and abbreviations
2 NvM Stack Overview
3 支持的同步机制(Synchronization Mechanism)
3.1 Implicit synchronization
3.2 Explicit synchronization
4. 其他机制
4.1 CRC 机制
4.2 错误恢复
4.2.1 对于 Read 操作的错误恢复机制
4.2.2 对于 Write 操作的错误恢复机制
4.3 写验证
4.4 NvMSetRamBlockStatusApi
4.4.1 During startup phase (NvM_ReadAll)
4.4.2 During shutdown phase (NvM_WriteAll)
4.5 Resistant to changed software
Abbreviation / Acronym: |
Description: |
NvM | NVRAM Manager |
NV | Non-volatile |
NVRAM | Non-volatile Random Access Memory |
NVRAM Block | The NVRAM Block is the entire structure, which is needed to administrate and to store a block of NV data. |
NV Block | The NV Block is a Basic Storage Object. It represents the part of a “NVRAM Block” which resides in the NV memory |
RAM Block | The RAM Block is a Basic Storage Object. It represents the part of a “NVRAM Block” which resides in the RAM. |
RAM Mirror | RAM mirrors are NvM internal buffer used for operations that read and write the RAM block of NVRAM blocks with NvMBlockUseSyncMechanism set TRUE. |
ROM Block | The ROM Block is a Basic Storage Object. It represents the part of a “NVRAM Block” which resides in the ROM. |
ROM | Read-Only Memory |
RTE | Runtime Environment |
SW-C | Software Component |
App | Application |
RTE | Run Time Environment |
上图同时展示了整个 NvM Stack 的构成。
如上图所示,AUTOSAR规定,App只能通过NvM(NVRAM Manager)来访问NV Memory(比如FLASH)。
根据App对NvM Block‘’s RAM的访问方式,数据同步机制可以分为两种:
AUTOSAR规范:在隐式同步机制下,一个NvM Block的 RAM 被映射到一个固定的 SWC,不建议共享RAM。 每当SW-C使用RAM block(temporary/permanent)访问NVRAM时,都必须确保RAM块的数据一致性,直到NvM完成正在进行的操作为止。
说人话:
在隐式同步机制下,RAM block 和 SWC 之间是一一对应的关系,其他SWC不能访问该RAM。SWC要保持数据的一致性是说,从SWC调用NvM接口到NvM内部操作完成前,SWC不能再改变该RAM中的值。但是该RAM可以被read。
补充(个人理解):
temporary RAM:一般指局部变量;
permanent RAM:一般指全局变量。
使用隐式同步机制时分参考步骤:
AUTOSAR 规范:在显式同步中,NvM会定义一个RAM mirror,用于与App的RAM block交换数据。 App将数据写入RAM block,然后调用NvM Write API(NvM_WriteBlock / NvM_WritePRAMBlock)。 NvM 调用API(NvMWriteRamBlockToNvM)将数据从 RAM Block 拷贝到RAM Mirror,进而写入 NV Block。
显示同步的优点:
显示同步的缺点:
NvM模块内部使用CRC生成例程(8/16/32bit)来对 NvM Block 进行相关的检查。当然是否使用CRC是可以配置的。NvM模块内的配置选项为 NvMBlockUseCRCCompMechanism,启用后,如果将要写入的数据(即RAM中的数据)没有改变,则NvM写入请求会被跳过。 基于此,使用CRC的风险在于:如果RAM中的数据内容改变了,但是改变前后计算得出的CRC一致,就会导致数据无法正常写入。因此,此选项应仅用于可以容忍此风险的 NvM Block 。
1. 隐式错误恢复:
NvM 模块对于 Native 和 Redundant 类型的NvM Block 的 Read 操作提供隐式的错误恢复机制,即如果配置了 NvMRomBlockDataAddress 或者NvMInitBlockCallback,则加载对应的默认数据。
2. 显示错误恢复:
对于任何管理类型(NATIVE,Redundant,dataset)的NvM Block,如果其配置了ROM数据,都可以使用显示数据恢复机制来恢复数据,方法是调用 NvM_RestoreBlockDefaults()这个API。当然,对于 Dataset类型的NvM block,在调用API之前必须设置相应的Index(指向ROM Block)。
3. 其他
NvM 模块对于Redundant 类型的NvM Block 的 Read 操作还提供一种错误恢复机制,即将默认数据加载到RAM中。
即重新重写写操作,不区分NvM Block的管理类型。
写验证即为,将RAM block中的数据写入NV block后,立刻将其回读并与RAM Block的原数据内容做比较,如果比较结果不一致:则再次执行写操作,如果启用DET,则同时回向DEM模块报告错误 NVM_E_VERIFY_FAILED;
如果回读比较失败,则不会再次执行读操作。
对于某些NVRAM块,可能需要保留相应RAM块的数据内容,以免其在NvM_ReadAll() 期间被覆盖,尤其是在NV块中的数据早于RAM块中的数据的场景下(例如当RAM中的数据尚未写入NV block时发生了热复位)。 在这种情况下,必须将RAM block分配在复位安全(non-initialized)的RAM区域中,并且必须将配置参数CalcRamBlockCrc==TRUE 和 NvMSetRamBlockStatusApi==TRUE。(·CalcRamBlockCrc==TRUE,意味着相应的NV块也具有/具有 CRC配置)
每当RAM中的数据发生变化时都需要调用NvM_SetRamBlockStatus(blockID,TRUE),NvM 模块会重新计算RAM中的CRC并将其存储在一个内部变量(该变量存储在 reset-fase 区域)。当然前提 NVRAM Block 配置了PIM或启用显示同步机制。
在ReadAll()期间,会重新计算RAM的CRC,如果计算得出的CRC和之前存储的CRC一致,则RAM block的内容不会改变。如果不一致,则会将NV Block中的值读到RAM中(即RAM会重写),如果读失败,则会将使用默认数据恢复RAM(即将ROM中的值读到RAM中或者调用InitBlock )
如果 NvMSetRamBlockStatusApi == FALSE,则 NvM_WriteAll() 会将所有 NVRAM Block 的RAM的内容拷贝到 NV Block中。当然前提是的这些 NVRAM Block 的要求配置: NvMSelectBlockForWriteAll ==TRUE 并且 配置了NvMRamBlockDataAddress 或者使用显示同步机制。
当然,为了提高 NvM_WriteAll() 的速度,我们可以将那些只有 RAM Block的内容发生变化的 NVRAM Block写到 NV Memory中,这就需要配置 NvMSetRamBlockStatusApi==TRUE。这种场景下,每当 RAM中的内容发生变化时,用户就需要调用 NvM_SetRamBlockStatus(BlockID, TRUE),从而告诉 NvM 模块在 NvM_WriteAll()时要处理该 NVRAM Block。
NvM 模块的 start-up(即NvM_ReadAll() 的处理过程)行为受2个配置参数 NvMDynamicConfiguration 和 NvMResistantToChang 的影响。
在ECU项目中,如果如何处理NVRAM block的配置变更并不重要,则必须配置参数 NvMDynamicConfiguration==FALSE。对于每个NVRAM Block 的配置参数NvMCalcRamBlockCrc:
如果更改了NVRAM block 的配置,而已经存储在NV memory(比如FLASH)中的 NV block 仍与旧配置相对应,则在NvM_ReadAll()过程中可能会出现严重问题。 例如,当添加新的NVRAM块时,许多其他块的标识符可能会隐式更改,这可能导致从NV存储器读取错误的数据。
在这种情况下,可以配置NvM模块,使其不使用NV memory 中的数据初始化RAM block。即配置参数 NvMDynamicConfiguration == TRUE。 这时候集成商要修改配置参数NvmCompiledConfigID 从而告诉 NvM模块 NVRAM配置已经更改。 NvM模块使用单独的NVRAM block 将 NvmCompiledConfigID 的值存储在NV memory中。 每次执行启动过程(NvM_ReadAll)时,NvM模块都会将存储在NV memory中的值与配置参数NvmCompiledConfigID的值进行比较。 如果两个值不相同,则NV memory 中的值将在下一个shutdown过程(NvM_WriteAll)中被新的配置值所覆盖。
在这种情况下,NvM 在 NvM_ReadAll()过程中会根据配置参数 NvMResistantToChangedSw 来决定如何初始化 NVRAM Blocks:
因此,一旦将某个 NVRAM Block 配置为 NvMResistantToChangedSw == TRUE,则集成商必须确保在ECU的整个生命周期内不得更改以下配置参数,否则可能将无法成功地从NV memory 中恢复数据:
注意:根据所使用的NvM,Fee和Ea模块的具体实现,可能会施加其他约束。 请参考相应的用户手册。
总结一下:
NvMNvM_ReadAll()的过程如下: