传送门 -> AUTOSAR配置与实践总目录
NvM 处于BSW中的Service层,具体的Memory Service协议栈分层如下
NVM: 全称NVRAM Manager ,存储服务管理模块。主要提供抽象数据存储,在上电读取下电存储数据,支持Immediately存储数据,将 NV data在ROM和RAM之间建立关联。
MEMIF: 全称Memory Abstraction Interface,存储抽象接口模块。实现存储数据Block在内部Flash或者外部EEP的分离操作。
FEE: 全称Flash EEPROM EMULATION,FLASH模拟模块。FEE实现对Flash的数据Block的抽象和动态数据的Layout。
FLS: 全称Flash Driver模块,主要提供操作Flash的接口。
EA: 全称EEPROM Abstraction,EEPROM抽象模块。定义外部EEPROM的存储抽象和数据的Layout;
EEP: 全称External EEPROM Driver模块。提供外部EEPROM的操作接口和驱动。
内部交互数据流:
Nvm通过MemIf_Read和MemIf_Write实现内部Flash或者外部EEP的读写操作。
当选用内部FLASH时候,数据流如下:
NVM—>MemIF—>FEE—>FLS---->Internal Flash访问路径(图中红色分支)
a) MemIf调用Fee_Read/Fee_Write接口实现对FEE模块操作,访问Flash前实现对Flash的数据Block的抽象;
b) FEE模块调用Fls_Read/Fls_Write接口实现对Flash的读写操作。
c) FlS 模块驱动模块与内部Flash硬件交互。
当选用外部EEPROM时候,数据流如下:
NVM—>MemIF—>EA—>EEP---->External EEPROM 访问路径(图中绿色分支)
A. MemIf调用EA(外部EEPROM的存储抽象接口)访问EEPROM前实现对EEPROM的数据Block的抽象;
B. EA模块调用External EEPROM Driver模块实现对外部EEPROM的读写操作。
C. EEP 模块驱动模块与外部EEPROM硬件交互。
基本存储对象说直白点就是存储形态,就是数据以什么样的形式存放的,是存在RAM里还是ROM中还是NV空间。
有同学说了,如果已经有了NV BLock那么还要RAM Block做啥,RAM Block的作用是在写入NV Block前,用户可以将数据先写到RAM Block中,再最终写入到NV BLOCK里面。
写入场景有时用户想在休眠时写入,有时用户想在特定周期延迟后写入,针对以上需求,RAM BLOCK可以较好满足用户需求。
读取时候类似的道理,先把数据从NV Block读到RAM中,所有用户可以通过RAM统一获取数据,而不是每次都从NV Block读取(耗费时间)
Native Block:
标准的块类型 ,是最常见的Block形式;
NV Block Header
存储Static Block ID信息, 只有配置Check Static Block ID的功能, Header才会存在。
NV BLOCK CRC
如果配置了CRC check 功能,则CRC部分才会存在。
Redundant NVRAM block:
通过该类型可以实现数据的冗余备份存储。
如有一份数据错了,可以用备份的那块
此类型旨在增加数据的可用性,以防出现错误,即不打算提供额外的错误检测。
主要的焦点在于写中止,特别是由于欠压条件而复位.用户数据在NV区存储两次。
NVM依赖于底层(FEE/EA)对写访问中止的检测,即使在写访问中止的情况下,也能确保可读数据块仍然是可读的。
Dataset NVRAM:
多个相等的数据块组成,每个数据块是独立的BLOCK
1.可通过Administrative Blocks获得获取对应数据块的index (NvM_GetDataIndex()和NVM_SetDataIndex)
2.此存储方式便于配置管理。如有多个variant Block存储数据含义相同,但是不同Variant数值有差异。
永久RAM块:
RAM块的地址是固定的, 存储在NVM的配置中。可以由一个应用程序访问NV块,也可以让多个应用程序访问同一个NV块。
非永久RAM块:
每个应用程序使用自己的RAM块。在这种情况下,RAM块称为非永久性块。由于RAM地址没有被存储(并且可能变化),因此必须给出一个指针来读写非永久块。
在NvM对数据的操作过程中存在两种同步机制,隐式同步和显式同步。
隐式同步简介:
APP中直接调用NVM的接口对数据进行操作,此种方式不推荐使用共享的RAM Block操作,在NVM中确保RAM Block数据的一致性(主要同步CRC机制实现)。
显式同步简介:
NVM定义了一个RAM Mirror用于和APP进行数据交换,APP调用NvM_WriteBlock的时候写数据到RAM Block中,此时数据仍然可以被修改。
因为数据还没有写到最终的Nv Block,调用NVM数据操作NvMWriteRamBlockToNvM的时候数据被Copy到内部的Mirror中,最后将数据写到Nv Block。
NVM在读的时候调用API从NvM_ReadBlock读取数据,在NvM调用了NvMReadRamBlockFromNvM后数据才真正的从RAM Mirror中Copy到了RAM Block。NvM提供了双向的控制Callback的路由,实现APP数据的传输。
隐式同步 SWC写入(读)数据流程如下:
应用SWC 通过RTE调用NV Interface类型接口触发NvSwc请求进行写(读)操作事件,传递RAMBlock参数给NVM用户数据写入(或从NVM读取)。
NvSwc调用 NvM_WriteBlock((或NvM_ReadBlock)) ,请求把RAM Block中的数据写入 NvBlock(或从NvBlock读取)。
从发起请求开始,到NvM模块读写完成为止,其他SWC不能更改RAM Block中的值,(虽可读取,为便于管理此期间一般禁止其他SWC读写操作)
SWC可以用轮询的方式周期性检查NvM写入(读取)操作是否完成,NvM也可以用回调函数的方式来通知SWC操作完成。
当NvM操作完成后,各SWC即可再次对Block进行读写操作了。
显式同步写入(读)流程如下:
应用SWC 通过RTE调用NV Interface类型接口触发NvSwc进行写(读)操作事件,若为写操作同时将数据传给RAMBlock。
NvSWC检测到写(读)操作事件,调用NvM_WriteBlock(或NvM_ReadBlock),发起一个写入(读)数据请求。读写函数数据指针为空,目的是发起一个写入(读)数据的请求。
NvM模块检测到读写数据请求会调用Write Ram Block To Nv Callback(或Read Ram Block From Nv Callback)这里配置的回调函数,在调用这个回调函数之前APP都可以修改RAM Block中的值。在Write回调中,
将用户Ram到NVM的mirror RAM(read则方向相反),进而调用NVM底层协议栈完成真正写操作(Read操作理解应为先执行协议栈再Copy数据)。
NvM模块调用读写Callback时,NV Block状态自动置为Busy,不允许其他SWC请求操作。
建议NvM用回调函数的方式通知APP操作结果。(轮询方式可能没有触发pending,导致read ok的结果是上一次的值!)
以上执行完成后,各SWC就可以再次对Block进行读写操作了。
下面从几个维度整理了两者差异:
RAM开销:
–> 隐式同步:无需多开辟RAM
–> 显式同步:
在显式同步中,采用了Mirror机制更好的防止数据一致性破坏,但是需要额外的RAM开销, 和NVM开辟的缓存(Mirror Block)两者有映射关系。
是否共享RAM:
–> 隐式同步:RAM(局部或者全局)由访问NVM的SWC独自使用;
–> 显示同步:RAM可单独使用,也可由访问NVM的各SWC共享。
数据一致性确保:
–> 隐式同步:
多用户访问较难确保数据一致性。
应用程序负责确保数据一致性,需要考虑的场景较多:
比如在读取作业完成之前,该块的擦除作业不能排队;
再比如一个擦除请求正在处理中,则可以读写RAM块,而不会对擦除作业的结果产生任何影响;
因此,对于隐式同步块访问最安全的方法是,只要RAM块处于挂起状态,就不要使用。
–> 显示同步:
多用户访问较容易确保数据一致性。
主要由NVM Mirror机制确保,除拷贝数据小部分时间外,其余时间均可修改和操作RAM Block;
在回调复制时,数据块是busy的(如下图Spec),所以APP需要通过读取NvM的操作状态来判断当前是否可以使用RAM Block。
操作占用时间:
–> 隐式同步:
–> 显式同步:
回调通知:
–> 隐式同步:
–> 显式同步:
传送门 -> AUTOSAR配置与实践总目录