基于 NOR Flash 实现 KV 数据库的应用研究

2022-03-09 04:45熊启龙
水利信息化 2022年1期
关键词:键值扇区遥测

熊启龙

(水利部淮河水利委员会水文局(信息中心),安徽 蚌埠 233001)

0 引言

水文自动测报系统中遥测站的常用参数必须实现在站存储,并且可以实时增加、修改、删除和查询。终端机作为遥测站的采集控制中心,通常都集成有非易失 Flash 固态存储器。非易失 Flash 固态存储器常用来存放运行参数、历史数据、日志信息、过程文件等内容,是遥测终端机重要的组成部分。

从微控制器(MCU)的角度看,遥测终端机中 Flash 可以分为以下 2 种:1)片内 Flash。片内Flash 空间有限,一般不用来存放频繁读写的数据。2)片外 Flash。片外 Flash 有 EEPROM,NOR Flash或 Nand Flash 等类型,采用通用标准接口与 MCU相连,可以用来存放频繁读写的数据。水文自动测报系统中大多数遥测终端机采用片外 NOR Flash 存放系统运行参数和设备运行期间产生的数据[1]。

根据 NOR Flash 的读、写和擦除特性,遥测终端机通常选用以下 1 种方式保存系统运行参数:1)依次存放方式。在以 1 个固定地址开始的存储区间内,依次存放系统运行参数[2],所有的系统运行参数组合在一起存放在 NOR Flash 中固定的 1 个或者多个连续扇区内。根据 NOR Flash 的擦写特点,参数的修改、擦除和写入必须以扇区为单位进行操作,此种操作方式没有考虑 NOR Flash 的擦写次数有限,频繁擦写固定的扇区可能会损坏该扇区,使存储器出现坏区。2)分块管理方式。以扇区为单位,在固定存储空间内为每个扇区建立头部信息,记录每个扇区的擦除次数、存储数据类型和分块状态,存放在每个扇区起始地址处。系统根据每个扇区的头部信息进行数据写入读取、资源回收和擦除次数均衡等操作,实现对固定的 NOR Flash 存储空间以分块管理的目的[3]。

遥测站系统运行参数是一种结构化数据,1 个参数可以用 1 个 KV(Key-Value)键值对进行描述,其中 Key 表示参数名,Value 表示参数数值,多个参数组成 KV 键值数据库。在同一个 KV 数据库中,Key 具有唯一性,KV 数据库具有简单易用、高效和可扩展性强等特点。当前,国内外常用的主流嵌入式 KV 数据库有 BerkeleyDB,Empress 和SQLite 等[4],这些嵌入式 KV 数据库性能强大,支持高并发操作,通常运行在 Linux 和 FreeBSD 等操作系统平台上,但是对于遥测终端机这种小型嵌入式设备来说,MCU 资源和性能有限,移植 Linux 和FreeBSD 等操作系统,以及 BerkeleyDB,Empress,SQLite 等嵌入式 KV 数据库非常困难,即使移植成功,也不能充分发挥高性能,因此需要针对遥测终端机的硬件特点和应用场景,设计一个 KV 数据库,满足遥测站日常运行应用需求。

在水文自动测报系统中,遥测终端机采用 NOR Flash 作为片外存储器,存储器资源和系统性能相对有限,运行过程中,需要频繁对其进行读写、修改和删除操作,且并发性操作要求不高,但是需要考虑存储器各扇区的磨损均衡和系统在异常情况下的掉电恢复功能,为此,本研究以终端机中常用的NOR Flash 存储器 W25Q256 为例,在资源有限的嵌入式终端设备中研究如何充分利用 W25Q256 的读写特点创建一个嵌入式 KV 键值数据库,满足水文自动测报系统中遥测站应用场景的需求。

1 W25Q256 读写特点

W25Q256 的容量为 32 MB,由 131 072 个可编程页组成,每个页的容量为 256 B,存储器 1 次最多可编程 1 个页,但是以 1 个扇区为单位进行擦除操作时,可以任意以字节为单位进行寻址读取数据。

为保证写入数据的正确性,通常在针对 1 个地址执行编程操作前,都要对该地址所在的扇区进行擦除操作,擦除后该扇区内的存储单元数值将全部为初始值 FFH,再进行写操作就可以正确完成。根据 W25Q256 的物理特征,在对每个字节进行编程操作时,每个位可以通过编程由 1 变为 0,但是不可以从 0 变为 1。因此针对 1 个存储空间可以重复写入,最终写入数值 = 要写入的数值 & 存储空间的原有数值。例如:在 Flash 起始地址为 1000H 的字节空间内写入二进制数值 1011 1111,该地址原有的二进制数值为 0111 1111,那么最终写入的数值为0011 1111。

从以上结果看,W25Q256 每次编程的最小写操作颗粒度为 1 bit,也就是针对 1 个编程操作的最小执行单位是 1 bit,执行结果要么是将 1 bit 的数值由1 变为 0,要么写入结果仍然为 1,不存在第 3 种可能,这是一个很重要的概念。

NOR Flash 的擦除和编程次数是有限的,根据W25Q256 存储器芯片的数据手册,针对同一个地址的循环擦除和编程次数如果超出 100 000 次[5],存储器芯片可能会损坏。

2 KV 键值数据库及实现功能

KV 键值数据库内的每一组 KV 键值对对应遥测终端机的 1 个参数,Key 具有唯一性,一旦保存,Key 值就不可被修改。

根据遥测终端机的应用场景,要在 W25Q256存储器创建嵌入式 KV 键值数据库,必须根据W25Q256 存储器的特点合理规划,最终要实现以下功能:

1)实现系统运行参数的快速插入、修改和删除操作;

2)要能根据参数名称,快速检索出数据库中参数对应的数值;

3)要考虑 NOR Flash 的磨损均衡操作[6]和系统运行参数的异常掉电恢复[7]功能。

3 KV 键值数据库实现方案

实现系统运行参数的在站存储操作,主要是在W25Q256 存储器的一段空间内建设 KV 键值数据库,实现任意参数的检索读取、新增写入、删除和修改。

3.1 参数的存放

在遥测终端机中实现参数的统一存放,就是在KV 键值数据库中依次存放 KV 键值对,在针对每个扇区存放第 1 个 KV 键值对前,需要对该扇区进行格式化擦除操作,保证该扇区在首次写入时数据全部为初始值 FFH。

为确保键值对操作的可靠性和数据的安全性,采用 C 语言为每个键值对定义一个描述结构体,具体如下:

struct KV_data {

uint8_t status; /*KV 键值对状态*/

uint32_t len; /*KV 键值对总长度,以字节为单位,为 Key 长度和 Value 长度之和 */

uint8_t key_len; /*Key 长度,键值对总长度为len,那么 Value 的长度为 len - key_len*/

uint32_t crc32;/*KV 键值对的 crc32 校验数值*/

} 。

结构体中 status 为 KV 键值对的当前状态,是实现 KV 键值数据库的关键,定义为如下 6 个数值(16 进制):

1)FFH,空白,表明该空间没有使用,宏定义为 UNUSED;

2)7FH,表明该空间准备或者正在写入内容,宏定义为 PRE_WRITE;

3)3FH,表明该键值对已经处于有效完好状态,宏定义为 WRITE;

4)1FH,表明该键值对正在准备删除,宏定义为 PRE_DELETE;

5)0FH,表明该键值对已经处于删除状态,不能再被使用,宏定义为 DELETED;

6)00H,表明该键值对检验错误,为错误状态,宏定义为 ERR_HDR。

从 6 个状态数值可以看出,相邻的 2 个状态数值只变化 1 bit,而且是从 1 变为 0,也就是W25Q256 的最小编程颗粒度。定义程序中每个 KV键值对的状态变化顺序只能从状态 1 到 6 变化,不能逆向变化。根据 W25Q256 的编程特点,针对 1 个KV 键值对的 status 状态数值存放位置,可以重复编程,从状态 1 到 6 依次顺序或者跳越变化。

每个 KV 键值对在存放到 NOR Flash 存储器前,一定要加上描述结构体,再在其后空间存放Key 和 Value 数据;在读取 KV 键值对时,首先读取该描述结构体,再通过描述结构体中信息读取KV 键值对。

所有 KV 键值对都按照以上描述结构体组成单元依次存放在 KV 键值数据库中,从而实现系统运行参数的保存。

3.2 参数的检索读取

由于 W25Q256 的擦除和编程次数有限,当需要检索 1 个系统运行参数时,不能采用在固定位置建立“索引”的方式快速定位检索 1 个参数对应的KV 键值对,而是采用循环读取 KV 键值数据库内所有 KV 键值对的方式检索参数:从起始位置开始依次读取 1 个有效完好状态的 KV 键值对,当 Key 对应的数值与要检索的参数相等就返回该 KV 键值对,该 KV 键值对的 Value 数值即要查询的参数数值。

3.3 参数的新增写入

当需要新增加 1 个系统运行参数时,首先在遥测终端机内存中新建 1 个类型为 struct KV_data的 KV 键值描述结构体,根据要新增写入的参数对应 KV 键值对计算 CRC32 校验数值,并填写描述结构体各字段,其中 status 状态初始化为 UNUSEED(FFH);然后从 KV 键值数据库存储器空间定位到有空闲空间的扇区,在该扇区的空闲起始地址处将该 KV 键值描述结构体写入,写入完成后将 stauts数值修改为 PRE_WRITE(7FH);再在紧随其后的空间开始将 Key 和 Value 依次复制,写入完成后将status 数值修改为 WRITE(3FH),此时该 KV 键值对已经处于有效完好状态,可以使用了。流程图如图1 所示。

图1 新增写入参数流程图

3.4 参数的删除

对遥测终端机系统运行参数的删除很简单,在KV 键值数据库中通过循环读取 KV 键值对,检索到该参数对应的 KV 键值对描述结构体,将其中 status字段修改为 DELETED(0FH),此时该键值对的状态为删除状态,不能再被使用了。

3.5 参数的修改

在遥测终端机中修改参数,并不是直接对该参数对应的 KV 键值对进行修改,而是采用如下步骤:

1)循环读取数据库中 KV 键值,对定位该参数对应的 KV 键值对,将其状态由 WRITE(3FH)修改为 PRE_DELETE(1FH);

2)在内存中申请 1 个状态为 UNUSED(FFH)的 KV 键值对描述结构体,根据参数的修改内容计算新修改参数的 CRC32 校验数值并填写描述结构体各字段,将该描述结构体在有空闲空间的扇区内(与原有参数 KV 键值对可能是同一个扇区,也可能不是同一个扇区)新增写入,写入完成后,将其状态由 UNUSED(FFH)修改为 PRE_WRITE(7FH);

3)在描述结构体后将新修改参数对应的 KV键值对写入,完成后将该描述结构体的状态由PRE_WRITE(7FH)修改为 WRITE(3FH),新修改的 KV 键值对处于有效完好状态;

4)将原有的 KV 键值对描述结构体状态由PRE_DELETE(1FH)修改为 DELETED(0FH),原有键值对为删除失效状态。

通过以上 4 个步骤,就可以完成参数对应的 KV键值对的修改,其中每次状态的改变都是针对该 KV键值对的描述结构体中 status 状态字段的重复写入,每次只变化 1 bit,且是从 1 变化为 0。修改系统运行参数的流程图如图2 所示。

图2 修改参数对流程图

3.6 异常掉电的恢复

假设在新增、修改或者删除参数的某个执行步骤过程中,遥测终端机突然掉电,修改没有完成,也就是新增加的 KV 键值对描述结构体状态可能为 UNUSED(FFH)或者 PRE_WRITE(7FH),而原有的参数对应 KV 键值对描述结构体状态为PRE_DELETE(1FH)。

系统重启后,将对 KV 键值数据库中所有的 KV键值对做如下操作:

1) 循环查询数据库中所有 KV 键值对的状态;

2) 如果发现 1 个 KV 键值对的描述结构体状态为 PRE_WRITE(7FH),表明该空间的键值对还没有写入完成,是无效数据,应立即将其 status 状态数值修改为 ERR_HDR(00H),也就是为错误状态;

3)如果发现 1 个 KV 键值对的状态为 PRE_DELETE(1FH),表明该 KV 键值对还没有修改完成,因此需要将该 KV 键值对进行恢复。系统将在数据库中新增 1 个参数,该参数对应的 KV 键值对数值与要恢复的 KV 键值对相同,新增完成后将原有 KV 键值的 status 状态由 PRE_DELETE(1FH)修改为 DELETED(0FH),原有键值对失效。

通过以上 3 个步骤,实现在异常掉电情况下系统重启后,对新增、修改或者删除参数失败的 KV键值对进行恢复。

3.7 实现的效果分析

在遥测终端机中基于 W25Q256 存储器中一段固定的存储空间内建立 KV 键值数据库,终端机在首次运行初始化后,将所有默认的系统运行参数依次新增写入数据库。在系统运行期间需要修改系统运行参数时,就修改数据库中对应的 KV 键值对;当需要删除 1 个参数时,就删除数据库中对应的 KV键值对。系统运行参数是系统稳定运行的基础,如果数据出现异常,将会导致系统运行出现不可预知的错误,采用 KV 键值数据库保存系统运行参数,充分考虑到 NOR Flash 存储器的特点和水文自动测报系统特殊的应用场景,可以有效提高系统的稳定可靠性。

KV 键值数据库中参数的新增、修改和删除操作都不可能存在对同一个固定地址频繁操作的情况,实现机制是按照数据库存储空间内地址依次增加而操作的,并没有在固定地址建立索引,当需要针对 1 个参数操作时,采用循环方式依次检索数据库中每个 KV 键值对进行相应操作,可保证 KV 键值数据库存储空间内每个扇区被擦除和编程的概率是基本一样的,达到磨损均衡的目的,能有效延长W25Q256 存储器的使用寿命。

4 结语

本研究充分利用 NOR Flash 的读写特点,基于W25Q256 存储器实现了一个 KV 键值数据库的设计,可对遥测终端机中系统运行参数进行新增、修改、删除和查询操作,从而使 W25Q256 的存储性能有了较大的改善,而且数据的可靠性也有很大提高,其最主要的特点是磨损均衡和异常掉电恢复,特别适用于遥测终端机中 NOR Flash 存储器无文件系统管理的参数存储。

在实际运行中,对 KV 键值对修改和删除过程中产生的状态为 DELETED 或 ERR_HDR 的无用键值对占用的空间要及时回收,以更有效地利用存储器空间。同时为加快访问 KV 键值数据库的速度,可以考虑在终端机内存中建立缓存区间,将常用的 KV键值对放入缓冲区,并建立 1 套缓存与 KV 键值数据库的管理机制。今后,针对 KV 键值数据库中资源回收和缓存机制功能需要做进一步研究和优化。

猜你喜欢
键值扇区遥测
分阶段调整增加扇区通行能力策略
前馈复合控制在提高遥测跟踪性能中的应用
非请勿进 为注册表的重要键值上把“锁”
远程控制式遥测地面站关键技术研究
基于WPF的遥测CAS信息实时监控系统设计开发
自适应模糊PID控制的遥测方舱温度调节方法
空中交通管制扇区复杂网络建模与特性分析
空域扇区网络级联失效抗毁性及优化策略
U盘故障排除经验谈
一键直达 Windows 10注册表编辑高招