AUTOSAR Flash EEPROM Emulation (FEE) 详解
目录
1. 概述
Flash EEPROM Emulation (FEE) 模块是AUTOSAR内存硬件抽象层的重要组成部分,其主要目的是在Flash存储器上模拟EEPROM的功能。由于Flash存储器和EEPROM工作原理不同,FEE模块通过特殊的管理策略解决了Flash有限擦写次数的问题,为上层软件提供了一种虚拟的、几乎无限次擦写的数据存储机制。
FEE模块为非易失性数据管理提供了关键服务,包括数据的读取、写入、擦除和块管理等操作。它是连接上层NVRAM管理器(NVM)和底层Flash驱动(Fls)的桥梁,使应用软件能够以统一的方式存储重要配置信息和运行时数据。
2. 架构设计
2.1 模块位置与接口
图2.1 AUTOSAR内存存储架构中的FEE模块
AUTOSAR存储架构主要分为四个层次:
-
应用层 - 包含各种应用软件组件,它们需要存储和读取非易失性数据
- 应用软件通过标准接口与NVRAM管理器交互
-
服务层 - 包含NVRAM管理器(NvM)
- NVRAM管理器:负责管理非易失性数据、处理冗余和CRC校验、调用底层Memory服务
- 为应用层提供统一的数据管理接口
- 处理数据备份、校验和版本控制
-
内存硬件抽象层 - 包含多个模块:
- 内存抽象接口(MemIf):提供统一访问接口,支持多种底层内存实现
- Flash EEPROM Emulation(FEE):提供虚拟地址方案和分段、"虚拟"无限擦写次数、块管理功能
- EEPROM抽象(EA):处理真实EEPROM设备的抽象
-
驱动层 - 包含具体存储设备的驱动:
- Flash驱动(Fls):直接控制Flash设备的读写操作
- EEPROM驱动:控制物理EEPROM设备
- 厂商特定库:提供特定硬件的底层支持
FEE模块通过内存抽象接口(MemIf)与上层NVRAM管理器连接,并且直接与Flash驱动交互,实现了对Flash设备的间接访问,同时隐藏了Flash存储器可擦写次数有限的特性。
2.2 内部状态管理
图2.2 FEE模块的状态机
FEE模块内部实现了一个状态机,用于管理模块的运行状态和操作流程。状态机包含四个主要状态:
-
MEMIF_UNINIT - 未初始化状态
- 模块尚未初始化
- 除
Fee_Init()
外的API调用将报错 - 模块启动后的初始状态
-
MEMIF_IDLE - 空闲状态
- 模块已初始化且空闲
- 可以接受新的请求
- 可以开始内部管理操作
-
MEMIF_BUSY - 忙状态
- 正在处理用户请求(如读取、写入、擦除等)
- 拒绝新请求(返回E_NOT_OK)
- 可以接受取消请求
-
MEMIF_BUSY_INTERNAL - 内部忙状态
- 执行内部管理操作(如垃圾回收、块整理等)
- 可以接受新用户请求
- 会延迟内部操作以执行用户请求
状态转换由以下触发条件控制:
- Fee_Init() - 将模块从UNINIT转换到IDLE状态
- 用户请求 - 如Fee_Read()、Fee_Write()等,将模块从IDLE转换到BUSY状态
- 内部操作 - 由模块自身触发,将模块从IDLE转换到BUSY_INTERNAL状态
- 操作完成 - 将模块从BUSY或BUSY_INTERNAL转换回IDLE状态
- Fee_Cancel() - 可以将模块从BUSY状态强制转换为IDLE状态
状态管理机制确保了FEE模块能够正确处理并发请求,避免资源冲突,同时保证数据一致性。
2.3 配置结构
图2.3 FEE模块的配置结构
FEE模块的配置系统包含多个层次的配置参数:
-
Fee_ConfigType - 顶层配置类型
- 包含指向块配置的指针
- 可能包含其他平台相关配置
-
Fee_BlockConfigType - 块配置类型
- BlockNumber:块编号(范围0x0001-0xFFFE,0x0000和0xFFFF为保留值)
- BlockSize:块大小(整数字节)
- ImmediateData:是否为即时数据块
- NumberOfWriteCycles:写入周期数
- DeviceIndex:设备索引
-
模块常量配置参数
- FeeDevErrorDetect:是否启用开发错误检测
- FeeVersionInfoApi:是否提供版本信息API
- FeeMainFunctionPeriod:主函数周期(秒)
- FeeVirtualPageSize:虚拟页大小,用于内部管理
- FeeMaximumBlockingTime:最大阻塞时间
- FeeIndex:FEE模块索引
配置结构允许用户定义多个数据块,每个数据块具有不同的大小和属性。系统集成商可以根据应用需求配置不同的块参数,以优化存储空间使用和性能表现。
3. API接口
3.1 接口功能分类
图3.1 FEE模块的API接口分类
FEE模块提供了一系列API函数,可以按功能分为以下几类:
-
初始化与配置
void Fee_Init(const Fee_ConfigType* ConfigPtr)
:初始化FEE模块void Fee_SetMode(MemIf_ModeType Mode)
:设置底层Flash驱动的模式
-
数据操作
Std_ReturnType Fee_Read(uint16 BlockNumber, uint16 BlockOffset, uint8* DataBufferPtr, uint16 Length)
:读取数据Std_ReturnType Fee_Write(uint16 BlockNumber, const uint8* DataBufferPtr)
:写入数据Std_ReturnType Fee_InvalidateBlock(uint16 BlockNumber)
:使块无效Std_ReturnType Fee_EraseImmediateBlock(uint16 BlockNumber)
:擦除即时块void Fee_Cancel(void)
:取消当前操作
-
状态获取
MemIf_StatusType Fee_GetStatus(void)
:获取模块状态MemIf_JobResultType Fee_GetJobResult(void)
:获取作业结果void Fee_GetVersionInfo(Std_VersionInfoType* VersionInfoPtr)
:获取版本信息
-
调度
void Fee_MainFunction(void)
:FEE主函数,由操作系统周期性调用
此外,FEE模块需要实现以下回调函数,用于接收Flash驱动的通知:
void Fls_JobEndNotification(void)
:作业完成通知void Fls_JobErrorNotification(void)
:作业错误通知
API接口的设计遵循AUTOSAR标准,统一使用Std_ReturnType
返回类型,返回值可能是:
- E_OK:请求被接受
- E_NOT_OK:请求被拒绝
作业结果可通过Fee_GetJobResult()
获取,可能的值包括:
- MEMIF_JOB_OK:作业完成且成功
- MEMIF_JOB_FAILED:作业失败
- MEMIF_JOB_PENDING:作业挂起(执行中)
- MEMIF_JOB_CANCELED:作业已取消
- MEMIF_BLOCK_INCONSISTENT:块不一致
- MEMIF_BLOCK_INVALID:块无效
3.2 错误管理
FEE模块实现了严格的错误管理机制,错误分为两类:
-
开发错误(如启用了开发错误检测):
- FEE_E_UNINIT (0x01):模块未初始化
- FEE_E_INVALID_BLOCK_NO (0x02):无效块号
- FEE_E_INVALID_BLOCK_OFS (0x03):无效块偏移
- FEE_E_PARAM_POINTER (0x04):空指针
- FEE_E_INVALID_BLOCK_LEN (0x05):无效块长度
-
运行时错误:
- FEE_E_BUSY (0x06):模块忙
- FEE_E_INVALID_CANCEL (0x08):无效取消
开发错误主要用于开发阶段的问题识别,而运行时错误则在系统实际运行过程中可能发生,需要应用软件正确处理。
4. 操作流程
4.1 写入操作序列
图4.1 FEE写入操作的序列流程
FEE写入操作的完整序列涉及多个组件之间的交互:
-
初始请求阶段:
- NVM向MemIf发起写请求:
MemIf_Write(DeviceIndex, BlockNumber, DataPtr, Length)
- MemIf将请求转发给FEE:
Fee_Write(BlockNumber, DataPtr, Length)
- FEE检查模块状态,如果状态为
MEMIF_UNINIT
或MEMIF_BUSY
,返回E_NOT_OK
- 如果状态为
MEMIF_IDLE
或MEMIF_BUSY_INTERNAL
,FEE接受请求:- 计算物理地址
- 设置状态为
MEMIF_BUSY
- 设置Job_Result为
MEMIF_JOB_PENDING
- 返回
E_OK
- NVM向MemIf发起写请求:
-
主函数处理阶段:
- Fee_MainFunction由操作系统周期性调用
- FEE检查挂起的作业
- FEE调用Flash驱动写入函数:
Fls_Write(Address, DataPtr, Length)
- Flash驱动接受请求并返回
-
完成通知阶段:
- Flash驱动完成操作后调用FEE的回调函数:
Fls_JobEndNotification()
或Fls_JobErrorNotification()
- FEE更新作业结果:
MEMIF_JOB_OK
或MEMIF_JOB_FAILED
- FEE将状态设置回
MEMIF_IDLE
- Flash驱动完成操作后调用FEE的回调函数:
-
结果通知阶段:
- 下一次Fee_MainFunction调用时,FEE通知NVM作业结果:
NvM_JobEndNotification()
或NvM_JobErrorNotification()
- 下一次Fee_MainFunction调用时,FEE通知NVM作业结果:
整个写入操作是异步的,初始API调用只接受请求,实际写入在后台进行,完成后通过回调函数通知上层软件。这种设计避免了长时间阻塞,提高了系统的响应性。
5. 总结
AUTOSAR Flash EEPROM Emulation (FEE) 模块是一个关键的中间件组件,它通过以下特性解决了Flash存储器在嵌入式系统中的使用挑战:
-
抽象层的价值:
- 提供统一的接口,隐藏底层Flash硬件细节
- 实现虚拟地址空间,简化上层软件的数据访问
- 解决Flash有限擦写次数的问题,延长存储器寿命
-
关键功能特性:
- 块管理:提供基于块的访问机制,支持不同大小和特性的数据块
- 虚拟无限擦写:通过磨损均衡和数据移动技术实现
- 异步操作:提高系统响应性,避免长时间阻塞
- 状态管理:通过状态机确保操作的有序执行和资源的正确分配
-
集成考虑:
- 配置灵活性:支持多种配置选项,适应不同应用需求
- 错误处理:提供完整的错误检测和报告机制
- 标准兼容:遵循AUTOSAR规范,确保与其他模块的互操作性
在汽车电子系统中,FEE模块使得关键参数(如里程数、诊断信息、用户设置等)能够可靠地存储在Flash存储器中,同时避免了Flash存储器擦写次数限制带来的寿命问题。通过合理的配置和使用,FEE模块能够显著提升系统的数据存储可靠性和灵活性。