MemStack 以NvM (Non-Volatile RAM Manager)模块向User提供各种非易失存储器的数据管理,NvM模块自身是独立于硬件的,但所有的功能都是直接访问硬件的,包括内部/外部的 EEP,或者是内部/外部的Flash 模拟的EEP。NVRAM 管理器处理对非易失性数据的并发访问,并提供可靠性机制,如单个数据元素的校验和保护。
MemService 由NvM MemIf EA Eep Fee Fls组成,支持对Flash 和Eeprom的数据集成管理,本文主要通过介绍NvM MemIf Fee EA 等模块来认识MemStack。
NvM 模块
Memory Service 通过将数据元素抽象成Block 进行统一管理,NvM所有的功能都是以Block为单元。NvM管理的Block包含:
1. Block 分类
NVM_BLOCK_DATASET。
每种类型的 Block 都由 NV Block、 RAM Block、 ROM Block 及 Administrative Block 等基本存储对象组成。
NVM_BLOCK_REDUNDANT 类型的 Block 包含两个 NV Block, 且两 NV Block 中保存的数据互为备份, 提高了数据安全性。
NVM_BLOCK_DATASET 类型的 Block 可根据需求配置多个 NV Block 或 ROM Block 并通过索引选择操作对象, 提高了系统的灵活性。
各类型 Block 存储结构如下图
2. Block 数据结构
虽然NvM中存在这么多类型的Block,但是在存储介质中实际存在的只有NV Block, Ram Block 和Rom 都不参与实际的写入过程。
一般来说NV Block 由Block Header + Block Data +Block CRC组成,其中Block Header会包含Block ID,用于写入/读取时校验
3. Block 任务分发
NvM 对NV Block的操作是独立于硬件,在NvM模块中无法直接写入对应的存储介质中。NvM通过识别Block的配置参数,确定当前操作的Block的下属模块,再将任务下发给MemIf模块。
当前操作的Block完成Job后,即可进行下一个Job操作。下面以NvM 操作Fee的Block为例
3.1. Block 任务队列以及Block 优先级
3.1.1. 任务队列
NvM 对Block进行读写操作,对于存储介质来说都是异步的。因此对于NvM是可以同时发起多个Block的读写操作(NvM_ReadAll/ NvM_WriteAll)。但是对于存储介质来说,当前操作的Block没有完成,无法接收下一个操作任务。因此NvM通过任务队列,同时结合回调函数或者轮询当前操作Job的状态(可配置),完成对多Block的任务管理。
3.1.2. 优先级 & Immdieta Job
NvM 提供两种任务队列, 一种为 FCFS(First Come First Serve ) 队列即先发出的请求会先被执行, 另一种为优先级队列即高优先级的请求会先被执行。启用 NvMJobPrioritization 时, NvM 使用优先级队列。Block 的优先级范围为 0…255,数值越小优先级越高。禁用 NvMJobPrioritization 时, NvM 使用 FCFS 队列。
NvM Block 可以通过将优先级设置成 Immdieta,该Block 可以越过FCFS 原则,进行优先处理。
4. Block 虚拟地址映射
NvM 通过 32 位的虚拟地址访问 Fee 及 Ea 模块, 16 位为 Block 地址偏移, 16 位为 Block Number。Block Number 分为 Block Base Number 及 Data Index 两部分, 二者的位数占比由配置 NvMDatasetSelectionBits 决定。Block Base Number 为(16–NvMDatasetSelectionBits)位, Data Index 为 NvMDatasetSelectionBits 位。当NvMDatasetSelectionBits 配置为 2 时, Block Number 如下图所示。
用户通过 Block ID 访问 NvM 的 Block, 而 NvM 通过下列计算方式访问 Fee/Ea 的 Block:
NvM Block Base Number = NvM Block ID << NvMDatasetSelectionBits
Ea Block Number/Fee Block Number = NvM Block Base Number + Data Index
下图展示了在 NvMDatasetSelectionBits 配置为 2 时, NvM Block 及 Fee Block 的关联关系及 Fee Block在 NV Memory 上的排布。
注意
5. 数据校验&Redunant
NvM配置参数中NVM_MAX_NUM_OF_READ_RETRIES 定义了最大的尝试次数
如果Block 属性是Redunant Block,那么当Read Block发生错误时,将会从备份Block读取数据恢复数据
当以上措施都失效时,Rom Block中的默认数据,可以将数据恢复到默认状态
MemIf 模块
Memory Abstraction Interface (MemIf)作为接口抽象层, 为 NvM 提供访问 Fee/Ea 模块的函数,NvM借此抽象成硬件无关的模块。
MemIf 通过Device Id将Fee 与EA 的相关接口抽象成MemIf接口供NvM访问
1. Device & Api管理
MemIf 可以同时管理EA 和FEE,通过NvM Block 的 DeviceId 配置属性,进行识别,在访问对应的Device Api
EA 的Device ID 0
Fee 的Device ID 1
Fee 模块
Fee(Flash Eeprom Emulation), 顾名思义就是Flash 模拟Eeprom. 那么为何不直接使用Eeprom,或者说Flash为什么需要模拟Eeprom.
Flash 与 EEP 都属于非易失存储器(Non-Valatile Memory),主要存在以下几点区别
成本
同样的存储空间,EEP比Flash贵上许多,因此一般MCU上Flash空间要比EEPROM 空间大
擦写方式
Flash 以Page为单位,擦除的时候 必须按照Page 为单位擦住,同时写入的时候,只能写1,也就是由0->1,因此如果要改写某个Page的一个Byte,那么必须先将Page的内容全部读到Ram,然后改写Ram中对应的变量,然后擦除该Page,最后把Ram修改后的值写入到Page,也就是需要以下三步:
读->改->写
Eeprom 支持按照Byte直接修改Fee,就是将Flash的写入操作,通过软件的模拟成EEP.
1. 模拟EEP写入方式
Fee 通过 Fls 模块操作 DataFlash, DataFlash 具有如下物理特性:
Fee 的写入单元是Block,Fee Block 是继承自NvM Block,在NvM Block 数据的基础上加上Fee Block Header数据,形成Fee Block。
Fee 写入Block 按照先写入,地址就靠前的原则,下次写入Block 就依次往后排。这样确保每次写入都不需要擦除。
2. Fee翻页机制
Fee 通过对Flash空间整体划分为两个逻辑Sector, 一个作为Active Sector,一个作为Inactive Sector。这两个Sector 由一个或者多个物理Sector组成。
在任意时间,只能有一个Logical Sector在作为 Active Sector只有当Active Sector,如何写入下一个Block,或者达到配置的剩余空间,那么就会进行翻页操作。翻页操作一般会经历如下几个步骤
翻页前
翻页后
注意,这里翻页操作时,并没有将所有的数据都由Active Sector搬运到Inactive Sector,而是将所有Block的最新数据搬运到Inactive Sector
3. Fee 初始化读取地址
Fee 提供地址管理机制,Fee 会在Ram中实施记录所有Block的当前地址和状态,在Block写入新的数据时,又会更新这个地址。这些地址主要用于Fee读取Block数据。
在Fee进行初始化之前,这些Block地址是未知的,因此需要在Fee 初始化阶段,需要从Flash 遍历得到当前Blcok的地址。
由下图可知,Fee写入是在Active Sector 中依次往下排布的,因此在最新的Block 数据往往在Active Sector的底部。
4. Fee 写入Block 管理
通过 Block 头信息中的有效标识位字段可以判断当前的扇区及 Block 是否有效。
在写任务中, 首先写入除有效标识位之外的 Block 头, 随后写入数据段, 最后写入 Block 有效标识位。
若在写任务中异常下电, Block 头中的有效标识位未成功写入, 重新上电执行完扫描任务后, 认为该 Block无效, 无法成功读取该 Block 的数据, Fee 向上层返回的结果为 MEMIF_BLOCK_INCONSISTENT。
EA 模块
由于EEP 是可以支持直接写入的,因此存储在Eep的Block地址都是固定的,Ea 模块为
EEPROM 硬件抽象层, 通过访问下层 Eep 模块提供的 API 操作 EEPROM 硬件, EEPROM 具有如下物理特
性:
由于 EEPROM 具有如上特性, Ea 可为每个 Block 确定具体的硬件存储地址并划分存储空间, NvM 在执行读/写等服务时, 通过 Ea 完成相应 Block 的地址映射即可操作 EEPROM 硬件中数据
1. EA 地址管理
通过获取 NvM Block 的类型、 长度等配置, Ea 按照各 Block 的长度为其分配地址空间, 从 0 地址起依次向后排列。
2. EA Block 写入管理
Ea Block 中包含块状态标识位, 该标识位会存入 Eeprom 中, 通过该字段可以判断当前 Block 是否有效。在读任务若发现标识位为无效的状态, 则直接向上层返回 MEMIF_BLOCK_INVALID 失败状态;若发现标识位不为有效/无效值, 则直接向上层返回 MEMIF_BLOCK_INCONSISTENT 失败状态。
————————————————
版权声明:本文为CSDN博主「Archieeeeee」的原创文章,转载请附上原文出处链接及本声明,已获作者转载权限。
分享不易,恳请点个【👍】和【在看】