NVM备份机制
介绍
系统中时常会分配一些NVM区存储掉电不丢失的数据。这时就会对NVM区进行读写操作, 未防止读写过程中数据的丢失, 所以可以设计备份机制提高系统的可靠性和稳定性。
在单片机系统中, 如果不带EEPROM, 则更多的把数据放置在flash中, 这种情况下需要规划好flash分配, 根据数据的大小, 一般放置于flash最后的空间。例如, flash大小为32k, 需要存放的数据为1k, 则NVM区地址为(32-1)k ~ (32k-1), 此时固件大小需要注意不能超过(32-1)k 。
向NVM区(Flash)写入数据可分为3步:
- 第一步, 将目标扇区内原有数据读出到RAM中;
- 第二步, 擦除NVM目标扇区内数据;
- 第三步, 将新数据和RAM中的旧数据写入到该扇区中。
基于以上写操作的特点可以看出, 若执行写NVM区操作的第二步或第三步时芯片断电了, 就会造成NVM区内原有数据丢失, 而新数据写入失败, 表现出NVM区内数据错乱的现象。
操作
第一次写入数据
第一步:将NVM区地址0x0000 ~ 0x00FF定义为Block1, 将0x0200 ~ 0x02FF定义为Block2。
#define Block1 0x0000
#define Block2 0x0200
第二步:定义一个256字节的数组databuf和一个标志位变量cnt, 并将cnt赋值0。
unsigned char databuf[256];
Unsigned char cnt = 0;
第三步:将目标数据(待写入数据)拷贝到databuf数组中, 并将cnt+1拷贝到databuf+255的位置。
databuf[255] = cnt+1;
第四步:调用WriteNVM函数向Block1写入数据databuf, 写入长度256字节。调用WriteNVM函数向Block2+255位置写入cnt, 写入长度1字节
WriteNVM(Block1, databuf, 256);
WriteNVM(Block2+255, &cnt, 1);
更新数据
第一步:调用ReadNVM函数分别读取Block1和Block2的标志位(最后一字节)。
unsigned char flag1, flag2;
ReadNVM(Block1+255, &flag1, 1);
ReadNVM(Block2+255, &flag2, 1);
第二步:判断两个Block的标志位大小, 选取标志位数值小的Block进行更新。将目标数据(待写入数据)拷贝到databuf数组中, 并将标志位加2后拷贝到databuf+255的位置。
if(flag1 > flag2)
{
cnt = flag2 + 2;
databuf[255] = cnt;
WriteNVM(Block2, databuf, 256);
}else{
cnt = flag1 +2;
databuf[255] = cnt;
WriteNVM(Block1, databuf, 256);
}
读取数据
第一步:读取Block1和Block2的标志位数据。
ReadNVM(Block1+255, &flag1, 1);
ReadNVM(Block2+255, &flag2, 1);
第二步:判断标志位大小, 数值大的Block内为新数据, 数值小的Block内为旧数据。
if(flag1 > flag2)
{
ReadNVM(Block1, databuf, 255);
}else{
ReadNVM(Block2, databuf, 255);
}
转载:https://zhuanlan.zhihu.com/p/77334802
更多推荐
所有评论(0)