嵌入式系统与单片机|技术阅读
登录|注册

您现在的位置是:嵌入式系统与单片机 > 技术阅读 > [Classic AUTOSAR学习]NvData(非易失型数据)的处理(一)

[Classic AUTOSAR学习]NvData(非易失型数据)的处理(一)

AUTOSAR中的Mem Stack

可变性和耐久性是ECU内部数据的两种属性,如果期望某个数据既保持可变性,又能让数据在不同的上电周期能够被读取到(也即掉电时数据不丢失),那么数据需要被存储在非易失型数据存储当中(Nvm)。

在AUTOSAR架构当中,应用只能通过NvM模块访问非易失型数据数据,NvM模块提供了数据管理与维护的同步/异步服务。

Memory Stack参考架构图如下:

由于R21-11版本中引入了MemAcc模块,本文参考的最新规范文档当中,并未在上图体现,MemAcc工作在FEE/EA模块之下:

本文主要分析AUTOSAR工程对于NvData的处理,不涉及MemAcc细节,之后有空单独写文章介绍MemAcc的功能。

基本存储对象

我们给NvRam划分不同的Block(块),而对于一个NvRam Block,其包含的最小实体为“基本存储对象”,它可以出现在不同的存储位置(RAM/ROM/NV memory)。

RAM Block

RAM Block代表的是存储在RAM区域,作为NvRam Block一部分的基本存储实体。它包含用户数据,CRC值(可选),NvBlock头部(可选)。它用来存储实时数据,是NvRam Block的可选部分。

ROM Block

ROM Block代表的是存储在ROM区域,作为NvRam Block一部分的基本存储实体。它也是NvRam Block的可选部分。

NV Block

NV Block代表的是存储在非易失型存储的NvRam Block的一部分基本存储实体。它是NvRam Block的必要部分。

NV Block的内容是永久存在的,也可以在程序执行期间被修改,保留在FLASH当中。它包括NV用户数据,CRC值(可选),NV Block头部(可选)。它用来存储可以周期或者基于请求而存储的实时数据。

Administrative Block

这个Block在RAM当中,是NvRam Block的必要部分。

Administrative Block的内容不是永久存在的,它用来保存对应NvRam Block的属性/错误/状态等信息,是Dataset类型的NvRam Block

块管理类型

Nvm支持以下NvRam Blcok管理类型:

Native NvRam Block

Native NvRam Block是最简单的块管理类型,它允许以最小的代价向非易失型存储中写入或者从这里读取数据。

NVM_BLOCK_NATIVE类型的NvRam存储包括的基本存储对象有:

  • NV Blocks: 1

  • RAM Blocks: 1

  • ROM Blocks: 0..1

  • Administrative Blocks: 1

Redundant NVRAM block

这个块可以提升Native NvRam Block的故障冗余度,可靠性以及可用性,作用在数据损坏时。NVM_BLOCK_REDUNDANT类型的NvRam存储包含:

  • NV Blocks: 2

  • RAM Blocks: 1

  • ROM Blocks: 0..1

  • Administrative Blocks:1

当NV Block被视为无效时,会尝试用未损坏的NV Block恢复数据。

Dataset NVRAM block

Dataset NVRAM块是一组等大小数据块的数组。应用可以单个操作即访问到其中某一个数据块。

NVM_BLOCK_DATASET类型的存储包含:

  • NV Blocks: 1..NvMNvBlockNum

  • RAM Blocks: 1

  • ROM Blocks: 0..NvMRomBlockNum

  • Administrative Blocks: 1

NV + ROM 块的总大小需要在1到255之间。

同步机制

Nvm支持两种写入/读取Nvm模块RAM镜像的同步机制。

隐性同步

在隐性同步机制当中,应用和Nvm模块并行访问同一个RAM Block。通过调用Nvm接口,应用向RAM中写入/读取数据。

在这种场景下,不推荐将RAM块关联到某一SWC,并且共享此RAM块。无论SWC何时通过RAM块访问NvRam,它都需要确保RAM块数据的一致性,直到Nvm完成操作。

隐性同步机制的步骤:

写请求:

  • 应用将待写入数据更新到RAM块

  • 应用调用NvM_WriteBlock/NvM_WritePRAMBlock接口,请求Nvm服务

  • 此后,应用不应当再修改RAM块数据,直到Nvm模块返回成功或失败的结果。当然,这个过程当中,可能还有其他的读取操作

  • 应用可以轮询获取结果,或者设置回调函数等待调用

  • Nvm模块操作结束后,可以再次修改RAM块数据

  • 多个块写入请求:

  • EcuM模块调用NvM_WriteAll接口

  • EcuM模块以轮询方式或者回调函数的方式获取结果

  • 显性同步

    在显性同步机制当中,Nvm模块定义一个用来交换应用RAM块数据的RAM镜像。应用将数据写入RAM块,并调用NvM接口,此后Nvm从RAM镜像读取数据,这个数据是从RAM块来的,最终会写入到NV Block。

    这种机制的好处是,应用可以更高效地控制RAM块。应用调用ReadRamBlockFromNvM/WriteRamBlockToNvM接口读取/写入数据到RAM镜像中,应用需要保证读取/写入过程中数据的一致性。

    至于缺点,则是需要NV Block等大小的额外的RAM消耗,数据拷贝操作也增加了。

    当存在NvBlock类型的Swc时,使用这个机制,就可以将NVRAM块共享给不同的应用。

    写入请求:

  • 应用将数据写入到RAM块

  • 应用调用NvM_WriteBlock/NvM_WritePRAMBlock接口

  • 在NvM调用NvMWriteRamBlockToNvM接口之前,应用还可以修改RAM块数据的值

  • 如果NvMWriteRamBlockToNvM被NvM调用,那么应用应当向NvM模块指定地址提供数据的拷贝。应用可以返回NOK表示数据不一致,在尝试了NvMRepeatMirrorOperations次数后,Nvm进行下一个请求。

  • 数据写入Nvm之后,应用才能再次读写RAM块

  • 应用可以通过轮询方式或者回调函数来获取结果

  • 多个块写入请求(NvM_WriteAll):

  • EcuM调用NvM_WriteAll

  • 在任务执行过程中,如果块设置了NvM_WriteRamBlockToNvM回调,那么应用需要向NvM模块指定地址提供数据的拷贝。应用可以返回NOK表示数据不一致,在尝试了NvMRepeatMirrorOperations次数后,Nvm进行下一个请求。

  • 此后,应用可以再次读写RAM块

  • EcuM可以通过轮询方式或者回调函数来获取结果

  • 其他功能

    CRC校验

    可选地,NvM内部可以为NVRAM Block生成CRC来作校验。

    如果开启了NvMBlockUseCRCCompMechanism选项,基于CRC值,如果检测到数据未发生变化,那么NvM可以跳过写入操作。

    错误恢复

    如果配置了NvMRomBlockDataAddress或者NvMInitBlockCallback,那么NvM提供隐性的错误恢复功能,为NATIVE和REDUNDANT类型的NVRAM块在发生错误的情况下,载入默认值。

    当然,也可以调用NvM_RestoreBlockDefaults接口显性地为所有类型地NVRAM块获取ROM中存储的默认值。对于DATASET类型,必须提供索引号。

    写入验证

    RAM Block数据被写入NV存储后,数据会被回读,以检查是否和RAM块中的值相同。

    如果不相同,那么会再次尝试写入,同事上报DEM事件NVM_E_VERIFY_FAILED。

    如果回读操作失败,那么则不会再次尝试。