AUTOSAR NVRAM Manager (NvM) 模块详解
目录
1. 概述
NVRAM Manager (NvM) 是AUTOSAR标准软件架构中的一个关键服务层模块,主要负责为软件组件 (SWCs) 和基础软件 (BSW) 模块提供对非易失性存储器 (如EEPROM和Flash) 的规范化访问。NvM模块作为软件上层应用与底层驱动之间的抽象层,通过提供标准化的数据块管理API,屏蔽了不同存储介质的技术细节差异,使得应用程序可以更加关注业务逻辑而不必处理底层存储细节。
NvM模块提供的主要功能包括:
- 管理非易失性数据的读写请求
- 提供冗余块存储支持
- 管理块数据的CRC校验和数据完整性保护
- 支持默认数据恢复
- 提供块锁定和写保护功能
- 支持与模式管理 (BswM) 的协作
2. 架构设计
2.1 模块架构
NvM模块在AUTOSAR架构中位于服务层,与其他服务模块和ECU抽象层紧密协作,下图展示了NvM模块的架构位置和关键交互关系:
NvM架构图解释:
-
应用层:
- SWCs (软件组件):
- 描述: 应用层的软件组件,通过RTE调用NvM服务来存取非易失性数据
- 功能: 实现应用功能,根据需求请求读取或写入配置数据、状态信息等
- 示例代码:
/* 通过RTE接口调用NvM读写功能 */ Std_ReturnType result; uint8 myData[10]; /* 读取操作 */ result = Rte_Call_MyNvData_ReadBlock(myData); /* 写入操作 */ myData[0] = 0x10; result = Rte_Call_MyNvData_WriteBlock(myData);
- SWCs (软件组件):
-
服务层:
-
NvM (NVRAM管理器):
- 描述: 核心模块,管理所有非易失性数据的存储和检索
- 功能: 提供标准化API接口,管理内存块,协调读写请求,处理错误和异常情况
-
BswM (BSW模式管理器):
- 描述: 管理基础软件模块的不同运行模式
- 功能: 接收NvM状态通知,协调多模块的模式转换
-
EcuM (ECU管理器):
- 描述: 管理ECU的整体状态和启动/关闭流程
- 功能: 与NvM协作,确保在ECU关机前完成关键数据的写入
-
FiM (故障管理器):
- 描述: 接收并处理NvM报告的故障信息
- 功能: 根据故障严重程度执行相应的故障处理策略
-
RTE (运行时环境):
- 描述: 应用层与基础软件层之间的通信中介
- 功能: 提供标准化接口,转发SWC发起的NvM请求
-
-
ECU抽象层:
- MemIf (内存抽象接口):
- 描述: 向上层提供统一的内存访问接口,屏蔽不同存储介质的差异
- 功能: 路由NvM请求到相应的存储驱动模块
- 示例代码:
/* NvM通过MemIf接口操作底层存储器 */ MemIf_StatusType memStatus; MemIf_JobResultType jobResult; /* 读取请求 */ memStatus = MemIf_Read(deviceId, blockId, dataPtr); /* 获取作业结果 */ jobResult = MemIf_GetJobResult(deviceId);
- MemIf (内存抽象接口):
-
驱动层:
-
EEPROM Driver:
- 描述: EEPROM存储器的底层驱动
- 功能: 处理EEPROM的物理读写操作,报告操作状态
-
Flash Driver:
- 描述: Flash存储器的底层驱动
- 功能: 处理Flash的物理读写和擦除操作,报告操作状态
-
2.2 组件交互
NvM模块与其他AUTOSAR组件的交互方式包括:
-
上行接口: NvM向上层应用和服务提供的接口
- 通过RTE向SWCs提供块数据管理服务
- 直接向其他BSW模块提供非易失存储服务
-
下行接口: NvM使用的底层接口
- 通过MemIf向下层存储驱动发送读写请求
- 接收底层存储操作的执行结果
-
横向接口: 与同层级模块的交互
- 向BswM报告作业状态变化
- 向FiM报告生产错误和扩展错误
3. 状态管理
3.1 状态转换
NvM模块在运行时会经历不同的状态转换,下图展示了NvM的主要状态及其转换条件:
NvM状态图解释:
-
未初始化状态 (NVM_UNINIT):
- 描述: 此时NvM未准备好接收任何请求,是模块上电后的初始状态
- 转换条件: 只有在调用NvM_Init()函数后才能转换到空闲状态
- 限制: 在此状态只能调用NvM_Init()函数,其他API调用将被拒绝
- 示例代码:
/* NvM初始化例程 */ void Appl_InitializeNvM(void) { /* 调用NvM初始化函数以转换到IDLE状态 */ NvM_Init(); /* 此时可以开始使用NvM服务 */ }
-
空闲状态 (NVM_IDLE):
- 描述: NvM已初始化且当前无活动作业,可以接受新请求
- 内部状态:
- 无作业: 等待请求到来
- 请求已接收: 请求已加入队列,等待MainFunction处理
- 转换条件:
- 收到新请求时,内部状态变为"请求已接收"
- MainFunction处理请求时,转换到NVM_BUSY状态
- 内部作业触发时,转换到NVM_BUSY_INTERNAL状态
-
内部处理中状态 (NVM_BUSY_INTERNAL):
- 描述: NvM正在执行内部作业,如NvM_ReadAll或NvM_WriteAll
- 转换条件: 内部作业完成后返回NVM_IDLE状态
- 特点: 此状态下仍可接受新的单块作业请求,但会排队等待执行
-
忙状态 (NVM_BUSY):
- 描述: NvM正在处理队列中的作业请求
- 内部状态:
- 读取作业相关状态: 初始化、调用MemIf读取、评估结果
- 写入作业相关状态: 初始化、写前检查、调用MemIf写入、完成处理
- 转换条件: 当前作业完成且无下一个作业时返回NVM_IDLE状态
- 干预机制: 可通过NvM_CancelJobs取消队列中的作业
3.2 工作状态
NvM模块通过内部状态变量跟踪每个块的工作状态,主要包括:
-
块状态: 表示块数据的有效性
- VALID: 块数据有效,可以正常读取
- INVALID: 块数据无效,需要恢复默认值
- UNKNOWN: 块状态未知,通常是初始状态
-
请求状态: 表示最近一次操作的结果
- NVM_REQ_OK: 请求成功完成
- NVM_REQ_NOT_OK: 请求失败
- NVM_REQ_PENDING: 请求正在处理
- NVM_REQ_INTEGRITY_FAILED: 完整性检查失败
- NVM_REQ_BLOCK_SKIPPED: 块被跳过处理
- NVM_REQ_NV_INVALIDATED: NV数据已被标记为无效
- NVM_REQ_CANCELED: 请求被取消
- NVM_REQ_REDUNDANCY_FAILED: 冗余检查失败
- NVM_REQ_RESTORED_FROM_ROM: 已从ROM恢复默认值
-
CRC状态: 表示块数据的CRC校验状态
- NVM_BLOCK_CRC_OK: CRC校验通过
- NVM_BLOCK_CRC_FAILED: CRC校验失败
- NVM_BLOCK_CRC_INCONSISTENT: CRC值不一致
- NVM_BLOCK_CRC_NOT_PROCESSED: CRC未被处理
4. 数据管理
4.1 块管理
NvM模块采用块数据管理方式,将非易失性存储器的空间划分为具有唯一ID的数据块。下图展示了NvM块管理的类结构:
NvM块管理类图解释:
-
NvM_ConfigType:
- 描述: NvM模块的主配置结构,由代码生成器生成
- 主要元素:
- BlockDescriptorTable: 所有NVM块描述符的数组
- ServicePriorities: 不同服务的优先级配置
- CommonConfig: 所有块共享的通用配置
- 示例代码:
/* NvM配置实例 */ const NvM_ConfigType NvM_Config = { .BlockDescriptorTable = NvM_BlockDescriptors, .ServicePriorities = { NVM_PRIORITY_LOW, /* 读服务 */ NVM_PRIORITY_HIGH, /* 写服务 */ NVM_PRIORITY_LOW /* 其他服务 */ }, .CommonConfig = { .MainFunctionPeriod = 10, .MinNumWaitStates = 2, .MaxNumReadRetries = 3, .MaxNumWriteRetries = 2, .StandardJobTimeout = 250, .ImmediateJobTimeout = 100, .MultiBlockJobTimeout = 500 } };
-
NvM_BlockDescriptorType:
- 描述: 定义单个NvM块的特性和行为的结构
- 关键属性:
- BlockSize: 块在RAM中的大小(字节)
- NvBlockLength: 块在非易失存储器中的大小(字节)
- BlockManagementType: 块管理类型(正常、冗余等)
- BlockJobPriority: 块作业优先级
- MaxNumReadRetries: 最大读取重试次数
- MaxNumWriteRetries: 最大写入重试次数
- NvBlockBaseNumber: 在底层驱动中的基本编号
- RamBlockDataAddress: RAM数据块地址
- RomBlockDataAddress: ROM默认数据地址
- InitBlockCallback: 块初始化回调函数
- SingleBlockCallback: 块操作完成回调函数
- StatusFlags: 块状态标志
- CrcSettings: CRC设置
-
NvM_BlockStatusFlagsType:
- 描述: 定义块的特性和状态标志的位域结构
- 主要标志:
- WriteBlockOnce: 块只能写一次
- WriteProtection: 块是否写保护
- ResistantToChangedSW: 块在软件变更时是否保留
- SelectBlockForReadAll: 块是否包含在ReadAll操作中
- SelectBlockForWriteAll: 块是否包含在WriteAll操作中
- CbkBlockProcessing: 是否使用回调处理
- BlockUseCrc: 是否使用CRC保护
-
NvM_BlockInfo:
- 描述: 维护块在运行时的状态信息
- 关键属性:
- State: 当前状态(UNINIT/IDLE/BUSY等)
- Status: 请求结果(OK/NOT_OK/PENDING等)
- ManagementType: 管理类型
- BlockDataAddr: 块数据地址
- CurrentJob: 当前作业类型
- RetryCounter: 重试计数器
- BlockCrcStatus: 块CRC状态
- Lock: 块锁定状态
4.2 配置结构
NvM模块的配置主要通过预编译配置参数和运行时配置结构组合完成:
-
预编译配置:
- 通过配置工具生成的宏定义和常量
- 影响模块功能和行为的基本参数
-
运行时配置:
- 通过NvM_ConfigType结构体提供
- 包含块描述符和通用配置参数
- 在初始化时作为参数传递给NvM_Init()
重要配置参数包括:
- NvMConfigBlockDescriptorTable: 块描述符表
- NvMMainFunctionPeriod: 主函数调用周期(ms)
- NvMSingleBlockJobTimeout: 单块作业超时时间(ms)
- NvMMultiBlockJobTimeout: 多块作业超时时间(ms)
- NvMMaxNumOfWriteRetries: 最大写重试次数
- NvMMaxNumOfReadRetries: 最大读重试次数
5. API接口
5.1 读写操作
NvM模块提供了一系列API用于数据读写操作,下面的序列图展示了典型的读写操作流程:
NvM API序列图解释:
-
初始化阶段:
- 调用链: App → NvM → BswM
- 流程:
- 应用程序或EcuM调用NvM_Init()
- NvM初始化内部数据结构
- NvM通知BswM当前作业模式为IDLE
- 示例代码:
/* 初始化NvM模块 */ void InitializeSystem(void) { /* 初始化其他模块 */ ... /* 初始化NvM,传入配置 */ NvM_Init(&NvM_Config); /* 继续其他初始化 */ ... }
-
单块读取操作:
- 调用链: App → RTE → NvM → BswM → MemIf → Driver
- 主要步骤:
- 应用通过RTE请求读取操作
- NvM验证参数并将请求加入队列
- NvM_MainFunction周期性执行时处理队列中的请求
- 通知BswM作业状态变为PENDING
- 调用MemIf_Read请求底层驱动执行读取
- 后续MainFunction调用中检查操作结果
- 处理CRC校验,更新块状态和RAM数据
- 如果配置了回调,调用块回调函数
- 通知BswM作业状态返回IDLE
- 示例代码:
/* 应用层读取操作 */ Std_ReturnType ReadMyConfiguration(void) { Std_ReturnType result; MyConfig_Type myConfig; /* 通过RTE调用NvM读取服务 */ result = Rte_Call_ConfigData_ReadBlock(&myConfig); if (result == E_OK) { /* 数据请求已成功加入队列 */ return E_OK; } return E_NOT_OK; } /* 在后续检查操作结果 */ void CheckOperationResult(void) { NvM_RequestResultType resultStatus; NvM_GetErrorStatus(MY_CONFIG_BLOCK_ID, &resultStatus); if (resultStatus == NVM_REQ_OK) { /* 读取成功完成 */ } else if (resultStatus == NVM_REQ_PENDING) { /* 操作仍在进行 */ } else { /* 处理错误 */ } }
-
单块写入操作:
- 调用链: 与读取类似,但增加了写保护检查和CRC计算
- 主要步骤:
- 应用通过RTE请求写入操作
- NvM验证参数和检查写保护
- 将请求加入队列
- NvM_MainFunction处理请求
- 计算CRC(如果配置)
- 通过MemIf调用底层驱动执行写入
- 操作完成后更新块状态
- 调用回调函数(如果配置)
- 示例代码:
/* 应用层写入操作 */ Std_ReturnType SaveMyConfiguration(void) { Std_ReturnType result; MyConfig_Type myConfig; /* 准备要保存的数据 */ PrepareConfigData(&myConfig); /* 通过RTE调用NvM写入服务 */ result = Rte_Call_ConfigData_WriteBlock(&myConfig); return result; }
5.2 状态查询
NvM模块提供了一系列API用于查询块和模块的状态:
-
NvM_GetErrorStatus: 获取指定块的最后一次请求状态
Std_ReturnType NvM_GetErrorStatus( NvM_BlockIdType BlockId, NvM_RequestResultType* RequestResultPtr );
-
NvM_GetStatus: 获取NvM模块的当前状态
Std_ReturnType NvM_GetStatus( NvM_StatusType* StatusPtr );
-
NvM_GetBlockInfo: 获取块的详细信息
Std_ReturnType NvM_GetBlockInfo( NvM_BlockIdType BlockId, NvM_BlockInfoType* BlockInfoPtr );
-
NvM_GetActiveService: 获取当前活动的服务ID
NvM_ServiceIdType NvM_GetActiveService( NvM_BlockIdType BlockId );
6. 总结
AUTOSAR NvM(NVRAM Manager)模块是连接应用层软件和底层存储驱动的关键中间件,提供了可靠、统一的非易失性数据管理服务。通过标准化的接口和健壮的数据保护机制,NvM确保了关键数据的安全存储和高效访问。
NvM模块的主要优势包括:
-
抽象性:
- 屏蔽底层存储介质的差异
- 为应用程序提供统一的数据访问接口
-
可靠性:
- 提供CRC保护机制
- 支持数据冗余存储
- 实现数据写入和读取的重试机制
-
灵活性:
- 支持不同优先级的数据块管理
- 提供多种数据保护策略
- 可配置性高,适应不同应用场景
-
标准化:
- 符合AUTOSAR标准规范
- 提供标准化的错误处理和状态报告
- 易于集成到AUTOSAR架构中