STM32 使用 Flash 存储数据时的一种管理办法
while(FLASH->
}
FLASH->CR |= FLASH_CR_PG; //功能选择,写入
while(Length > 0)
{
*WriteAddress = *ReadAddress; //Ram to Flash program, 16bit each
while(FLASH->SR &= FLASH_SR_BSY);
WriteAddress += 1;
ReadAddress += 1;
Length -= 1;
}
FLASH->CR &= ~FLASH_CR_PG; //Clear PG bit
FLASH->CR |= FLASH_CR_LOCK; //Lock flash
以上的写入过程之前,必须确保要写入的 flash 位置首先擦除过,或者说要保证要写入数据的地方的值为0xFFFFFFFF,否则无法写入,硬件会有标志位来报错。
这样以结构体为单位擦写 flash 的好处是,如果需要修改要储存的数据数量或类型的话,只需要修改结构体定义就可以了,而且用结构体来管理变量,程序的可读性较好。
最后就是 flash 的擦写次数问题了,最少10k次的擦写寿命,对于某些需要频繁更新的内容还是太少了,比EEPROM 通常的 100k 少了一个数量级,而且即使是改动一个变量,也必须首先擦除整个 flash 块,更加速了 flash 的消耗。但是 stm32 的 flash 容量还是不错的,动辄 256Kbytes,所以我们可以用容量换寿命,
具体思路就是不要在同一个地址重复擦写,写的时候不停的变换地址,写满以后再擦除。比如,需要储存的结构体长度为 20x16bit,那么一个 2Kbytes 的 flash 页就可以储存 50 个相同的结构体,那么执行完 50 次写操作以后才需要执行一次擦除操作,flash 的使用寿命随之大为延长。还是以储存一个结构体为例说明如何实现这种储存方式,首先定义结构体,除了你需要储存的数据以外,还要额外增加一个变量,用于识别你当前读写的 flash 地址:
typedef struct //构造结构体
{
unsigned char flag; //用于识别当前地址的标记
unsigned char name[16];
unsigned char male;
float height;
float weight;
}Personal_Information_TypeDef;
#define Length (6) //结构体总长(16bit单位)
#define FLASH_ADDRESS (0x0803F800) //flash地址
#define Personal_Data ((Personal_Information_TypeDef *) FLASH_ADDRESS )
Personal_Information_TypeDef Personal_Data_Mirror; //ram中的结构体
这部分除了结构体中增加了一个标记(flag)变量以外,其它部分相同,但是思想上,我们其实是在 flash 中定义了一个结构体数组,只不过没有使用通常的[]来遍历数组变量,取而代之的是直接使用指针来操作。每次写入时,将 flag 变量固定写为 0x00。需要读取 flash 数据时,就可以根据标记变量 flag 的值找到最新的 flash 数据地址:
#define FLASH_ADDRESS_MAX; //最大偏移量,防止跨区块操作
unsigned short FlashAddress_Offset = 0; //用于储存flash地址偏移量的临时变量
while( (Personal_Data + FlashAddress_Offset) -> flag == 0x00)
{
FlashAddress_Offset += 1;
if( (FlashAddress_Offset + FlashAddress_Offset) > MAX_OFFSET)
{
break;
}
}
找到写有数据的 flash 地址以后,后继的写操作和读操作和单个结构体的操作相似,写的地址变为:(Personal_Data + FlashAddress_Offset)
读的地址是:
(Personal_Data + FlashAddress_Offset - 1)
具体实现时要注意,结构体的长度要算好,不能出现两个结构体交叉写入;擦除 flash 需要时间,此间最好不进行需要读取 flash 的操作。
STM32Flash存储数据管理办 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)