基于嵌入式MCU数据Flash的数据存储及管理方法研究与实现
具体实施
本文引用地址:https://www.eepw.com.cn/article/170167.htm数据分区设计
首先根据嵌入式系统的应用需求和MCU内部数据Flash的扇区大小,合理设置数据分区大小和个数,将数据Flash的若干扇区划分为多个数据分区,其取值均为2的n次幂,分区以0,1,2…进行编号,个数不大于256。分区大小和个数的设置和数据Flash的扇区长度匹配起来,满足以下公式:
分区大小*分区个数=扇区大小*扇区个数 (1)
在每个数据分区的起始地址设置分区状态字,反映数据分区的存储历史时间,在分区擦除后的第一次写操作完成后更新。设置数据条目的格式为data id+data,data id取值区间为[0,254],为每个数据条目的data id和data分配偏移地址,建立数据序列,组织数据分区,数据分区的格式为:分区状态字+ data id 1 + data 1 + data id 2 + data 2…。数据分区这样的存储结构非常适合需要进行多个独立数据存储的嵌入式系统应用,通过数据分区的格式定义,对其某个数据的寻址非常简单。
数据读取操作
数据读取操作在最新数据分区上进行,首先通过数据条目的data id进行偏移地址查表,然后根据最新数据分区编号进行地址计算,计算公式如下:
地址=0号分区首地址+(最新数据分区编号*分区大小)+偏移地址 (2)
和EEPROM的读取方式一样,直接读取该地址便可以得到数据[5],读取操作不会改变最新数据分区及其状态字。其软件实现如下所示:
void ReadEeprom(uint16_t data_id, void *dest_addr,uint16_t size)
{
u_EepromWord eedata;
uint16_t src_addr;
src_addr = GetDataAddrFromItsId(data_id);
src_addr += (Active_bank * EEPROM_SIZE_BYTES);
while(0 != size){
eedata.word = READFLASH16(src_addr);
*(uint8_t*)dest_addr = eedata.byte.msb;
((uint8_t*)dest_addr)++;
src_addr++;
size--;
}
}
数据写操作
在数据条目的设计中,将数据条目的data id存储地址同时做为数据状态字的存储地址,在写操作时通过数据状态字判断该数据条目地址是否执行过擦除操作,从而避免不必要的分区拷贝和扇区擦除操作,降低数据写操作代价[6]。首先根据公式(2)计算数据在最新数据分区的存储地址,读取其data id存储位置得到数据状态字,判断该数据在最新数据分区的写入地址是否已经被擦除。如果数据状态字等于0xff,表明写入地址已经被擦除,按照Flash的写操作命令序列在data id地址处写入data id,在data地址处写入data;如果数据状态字不等于0xff,表明写入地址未被擦除,需要进行分区拷贝操作,操作完成后更新最新分区及最新分区状态字。数据写操作流程如图2所示。

评论