往期小怿向各位小伙伴介绍了Classic AUTOSAR的OS模块,相信看过的小伙伴对Classic AUTOSAR的OS已经有基本的认知了,本期我们将继续介绍Classic AUTOSAR专题之存储模块的知识。
目录
1.AUTOSAR存储模块概述
2.NvM功能简介
3.应用层SWC如何访问NvM
4.小结
01 AUTOSAR存储模块概述
本文中的存储概念主要是指将数据存储在ROM中,且断电不消失,这种类型的数据也被称为“非易失性数据(NV Data)”。我们在实际开发中难免会有一些数据需要存储到ROM中,以备后续使用,比如DTC状态、快照数据以及扩展数据等,后续车辆检修时能为我们对故障的分析提供便利。
存储服务除了能用在诊断上,还可以用在上层应用开发过程中,用来存储一些必要数据。目前用户能用的ROM存储方式一般有两种:EEPROM(简称Eep)和FLASH仿EEPROM(简称Fls)。这些存储部件可以是片内的,也可以是片外的,如果是片外存储则一般需要通过SPI实现主芯片与片外ROM的通信。
Tips
EEPROM (Electrically Erasable Programmable Read Only Memory),电可擦可编程只读存储器--一种掉电后数据不丢失的存储设备,简称Eep。可以随机访问和修改任何一个字节,可以往每个bit中写入0或者1。掉电后数据不丢失,具有更高的可靠性,但是电路复杂,成本也高。
Flash表示Flash Memory的意思,是存储芯片的一种,即平时所说的“闪存”,可以通过特定的程序修改里面的数据,全名叫Flash EEPROM Memory,简称Fls。它的最大特点是必须按块(Block)擦除,但成本相对较低。
如下图1所示,按照Classic AUTOSAR的分层架构思想,存储模块在BSW中主要分为存储服务、存储硬件抽象以及存储驱动组成。
图1 Classic AUTOSAR架构中存储相关模块
存储服务
存储服务(Memory Service)只包含一个模块,即NVRAM Manager(简称NvM),NvM负责管理非易失性数据的读写以及擦除等操作,是应用层访问非易失性数据的唯一接口,并提供非易失性数据管理机制,如保存、加载、校验、保护、验证以及可靠存储等。
存储硬件抽象
存储硬件抽象(Memory Hardware Abstraction)是从存储设备(片内或片外)和ECU硬件布局中抽象出来的一组模块,主要作用对EEPROM以及Flash存储器访问的抽象,并封装成抽象接口(MemIf),通过存储抽象接口实现对这两种硬件的通用访问,并提供一组相同的API接口实现对不同厂商、不同类型存储设备的读、写、擦除等操作。
存储驱动
存储驱动(Memory Drivers),片内或片外ROM(EEPROM或Flash)的驱动程序,一般由芯片厂商提供。
上述存储相关的三大模块相互配合即可实现让用户在应用层对非易失性数据的轻松访问。
如下图2所示,用户在应用层通过RTE调用NvM模块的NvM_WriteBlock(NvM_BlockIdType,const void*)接口即可实现非易失性数据的写入功能,数据写入完成后,NvM会通过NvM_JobFinishedNotification(NvM_ServiceIdType,NvM_RequestResultType)通知用户数据写入结果。在整个写入过程中,用户无需关心NvM是如何将数据写入Fls或者Eep存储设备的。
图2 非易失性数据的写入时序示例
通过以上非易失性数据的写入时序示例,相信小伙伴们也感受到了在Classic AUTOSAR中NvM是应用层程序访问非易失性数据的唯一接口,它是用户和存储设备之间的一道桥梁,极大地简化了用户访问非易失性数据的复杂性,用户只需通过NvM提供的服务接口即可实现对NV Data的操作,无需关心NvM是如何操作Fls或者Eep的。下面我们将重点介绍一下NvM模块的主要功能。
02 NvM功能简介
NvM (Nonvolatile Memory Manager)也如ComM一样,是一个“管理者”,可以管理CAN、LIN、ETH这些总线。不同的是ComM是负责通信管理,而NvM负责存储管理,可以管理Flash、EEPROM这些存储器,做到了对不同硬件的统一管理。NvM主要具有以下的功能:
❶ 通过Client/Server Port向NvM User提供服务,NvM User可以是应用层SWC也可以是BSW中其他模块。NvM提供的服务接口如下表1所示。
Service Interface Name | Description |
NvMAdmin | 设置/重置NV块写保护 |
NvM_Mirror | 回调例程,为了让应用程序从NvM模块的Mirror复制数据到RAM Block,或者从RAM Block复制数据到NvM模块的Mirror |
NvM_NotifyInitBlock | 当需要将默认数据恢复到RAM Block时,NvM模块调用的回调函数 |
NvMNotifyJobFinished | 当对Fls或者Eep操作完成时Nvm调用的回调函数,通知NvM User操作完成情况 |
NvMService | 提供NV数据的读、写、擦除,获取NV Block状态,恢复NV Block到默认值等功能 |
表1 NvM提供的Service清单
❷ 排队管理机制,当有数据想要存储时,由于Flash和EEPROM都需要先擦除再写入,速度会比RAM慢很多,这就必然会产生数据的排队。而排队机制可以配置成FIFO或者是带有优先级的队列这两种方式,也可以配置成立即数据(immediate data),即可以不用排队。
❸ 上下电的存储处理,即在上电的时候,从Fls或者Eep中读取必要的数据并同步给RAM Block,在下电的时候,要将RAM Block必要的数据写入Fls或者Eep中。
❹ 支持数据校验:利用CRC校验检查是否数据出错,支持16bit和32bit的CRC校验,当校验出错时,触发使用默认数据。
❺ 数据的写保护,提供对NV Block的一些保护措施,比如单次写入,仅允许写入一次。
❻ 对数据的冗余存储,提供冗余机制,增加一些关键数据的可靠性。
2.1 NVRAM Block组成结构
在通信设计时,我们会使用IPDU来管理和缓存通信数据,NVRAM Block的作用与IPDU类似,其目的主要是用一些特殊的数据结构来存放和管理我们的NV Data。
在上图2所示的非易失性数据的写入时序示例中,我们可以看到用户是不能直接操作Fls/Eep的,需要在RAM中开辟一块儿区域(RAM Block)暂存我们要写入NV Block的NV Data。NV Data在写入NV Block前一般还需要CRC检验,如果校验出错时可以从ROM Block中获取默认数据作为Nv Data的替换数据。NVRAM Block的一些属性与状态信息(比如写保护)也需要RAM中开辟一块区域存储,方便NvM User随时查看。
因此在Classic AUTOSAR中NVRAM Block就被设计成了下图3所示的样子,NVRAM Block包含NV Block、RAM Block、ROM Block(可选)以及Administrative Block四部分组成。
图3 NVRAM Block内部结构
名称 | 描述 |
Basic Storage Object | 是一个最小的NVRAM block实体,多个Basic Storage Objects可以组成一个NVRAM Block。一个Basic Storage Object可以驻留在不同的内存位置(RAM/ROM/NV Block)。 |
NVRAM Block | NVRAM Block是管理和存储 NV Block所需的整个结构。 |
NV data | 要存储在NV Memory(Fls,Eep)中的数据。 |
RAM Block | 常驻于RAM空间,NV Block在RAM中的一个映射,因为应用层一般不直接操作NV Memory(那样的话太慢了)。 |
ROM Block | NVRAM Block的一部分(可选),常驻于ROM空间,用于存储默认值,以便当NV Block数据出现损坏时予以替换。 |
NV Block | NVRAM Block的一部分,常驻于NV空间。存储于NV Memory(Fls,Eep),可以选择是否添加Header和CRC校验。 |
Administrative Block | 常驻于RAM,是NVRAM Block必选部分。用来保存NVRAM Block的一些属性、错误和状态信息,以及datasets等信息,专门用于对NVRAM Block 与RAM Blcok 的数据安全性进行管理而设计的。 |
表2 NVRAM Block描述
2.2 NvM冗余机制简介
NvM支持三种存储类型,如下图4所示,分别是NVM_BLOCK_NATIVE,NVM_BLOCK_REDUNDANT,NVM_BLOCK_DATASET。
NVM_BLOCK_NATIVE:将一个RAM Block保存到对应的一个NV Block中,无冗余。
NVM_BLOCK_REDUNDANT:将一个RAM Block保存到两个NV Block中,具备冗余功能,当一个数据失效后可以使用另一个。
NVM_BLOCK_DATASET:将一个RAM Block保存到最多支持255个NV Block中,多重冗余,可以通过DataIndex来索引相关NV Block中的数据。
图4 Block management types
2.3 NvM API类别
为了使NvM模块适应不同的硬件资源,AUTOSAR为NvMService接口定义三种不同类别的API,不同类别的API所支持的功能有所不同,在实际使用过程中应根据硬件资源选择合适的API类别。API与API类别的对应关系如下表3所示。
API configuration class 3:所有指定的API调用都可用,支持全部功能。
API configuration class 2:一个中间的API调用集,部分功能是可用的。
API configuration class 1:最小API调用集,只有一小部分功能可用,特别适用于硬件资源非常有限的情况。
表3 NvM API总览
在上表3中可以看到Type2和Type3中的API都是异步调用方式,NvM提供了两种异步调用机制,分别是Polling和Callback。
所谓Polling就是NvM user以轮询的方式通过调用NvM_GetErrorStatus(...)去查看对NV Block的操作结果,如果返回NVM_REQ_OK则表示操作成功,如果返回NVM_REQ_PENDING则需要继续轮询。而Callback则是NvM User调用操作命令后就去干别的事儿了,NvM user只需以服务提供方的角色实现服务接口:NvMNotifyJobFinished。NvM在完成操作后以服务消费方的角色主动调用该服务接口,通知NvM user对Fls或Eep的操作结果。
03 应用层SWC如何访问NvM
前面对NvM的主要功能、NVRAM Block内部结构、NvM冗余机制以及NvM API类别做了简要的介绍,这些都是原理层面的内容,了解即可。那在实际开发中,Application SW-C(简称ASWC)是如何通过NVRAM Block实现对Fls或者Eep的读写、擦除等操作呢?
AUTOSAR主要提供了三种方式来实现ASWC是对Fls或者Eep的读写功能。
方式一
ASWC accessing NVRAM Block without PIM
如下图5所示,ASWC通过C/S Port直接调用NvM提供的服务(服务描述可参考表1), ASWC通过NvM_Write/ReadBlock API,实现NV data的写入或者读取的功能。
图5 ASWC accessing NVRAM Block without PIM
由于没有PIM(persistency memory),即在应用层没有固定缓存,ASWC每次读取或者写入数据都需要调用一下NvM_Write/ReadBlock API,并且需要传递一个指针。在写入Nv Data时,指针指向要写入的数据;在读取数据时,指针指向Nv Data在ASWC中存储位置,一般一个变量。NvM在完成操作后,会通过JobFinished(...)回调函数通知应用层操作结果。如果是读取操作,只有在收到JobFinished(...)通知后才能从指针上获取到数据。这种场景无法实现多个ASWC对同一个NV Data的操作。
方式二
ASWC accessing NVRAM Block with PIM
如下图6所示,这种方式与方式一相比,ASWC多配置了一个PIM(persistency memory),而且PIM在NvM中有对应的镜像。所谓PIM,可以暂时类比为ASWC中的一个静态全局变量,但是对PIM的读写都必须通过RTE实现。
图6 ASWC accessing NVRAM Block with PIM
这种方式ASWC一般也需要通过C/S Port与NvM连接起来,ASWC读写NV Data时通过操作PIM实现,此时数据暂存在镜像中,还没有同步到Fls或Eep中,在控制器下电时,NvM才会将数据写入到Fls或Eep中,当然ASWC也可以主动调用NvM_Write/ReadBlock API立即实现镜像与Fls或Eep的同步。在调用API的过程中,ASWC只需传递一个空指针即可,因为数据存放在镜像中,在调用接口后NvM会主动将镜像的数据与Fls或Eep同步。这种场景也无法实现多个ASWC对同一个NV Data的操作。
方式三
ASWC accessing NVRAM Block by NvBlockSwC
如下图7所示,在ASWC与NvM模块之间多了一个NvBlockSwC。ASWC写NV Data时通过Nv Port(与Sender/Receiver Port类似)将数据传给NvBlockSwC,NvBlockSwC收到数据后再通过C/S接口去调用NvM_WriteBlock(...) API向NvM请求写数据,再由NvM管理并写入数据到Fls或Eep。
图7 ASWC accessing NVRAM Block by NvBlockSwC
要实现这个过程还需要我们为NvBlockSwC设计相关Runnable去监听NvBlockSwC过来的数据,并调用NvM_WriteBlock(...) API。当ASWC读取NvData时,我们可以通过设计一个C/S接口向NvBlockSwC请求数据,NvBlockSwC收到ASWC的请求后,再向NvM请求读取收据,NvBlockSwC收到NvM的响应后再将数据通过NvPort发送给ASWC。
方式三的实现过程虽然要麻烦一些,但是这种方式可以实现多个ASWC对同一个NvData的访问,且不用但心数据一致性的问题。
我们在设计NvBlockSwC时还需要为其设计NVBlockDescriptor,NVBlockDescriptor主要是用来描述NV Data的RAM镜像的,用来映射NvBlockSwC中Nv Port和RAM Block,以及RAM Block与NvM中NVRAM Block映射,通过这种分层架构的设计,使得Nv Data有操作的空间,进而实现多个ASWC共享一个NvData。
除了上述的三种方式,AUTOSAR还对方式三定义了一些变种,由于时间关系就不一一介绍了,感兴趣的小伙伴可以参考《AUTOSAR_EXP_NVDataHandling》做进一步的了解。
04 小结
本文主要对Classic AUTOSAR中存储模块的分层架构以及NvM的主要功能,比如NVRAM Block组成结构、冗余机制以及NvM API类别等做了简要的介绍,并且分享了ASWC访问NVRAM Block的三种常见方式。希望读过文章的小伙伴能够有所收获,由于时间关系难文章免存在一些不足的地方,有疑问的小伙伴可以在后台提问,我们会及时响应,共同探讨。之后我们还会陆续推出AUTOSAR其他模块的介绍,期待您的关注。
喜欢此篇文章的话欢迎点赞、评论、收藏、分享支持小编~