AnsweredAssumed Answered

STM32F3 USERFLASH UTILITY - USING FLASH AS "EEPROM" - HERE

Question asked by harrison.david on Jul 4, 2015

Hi, all. I wanted to use a portion of the STM32F303 FLASH as "eeprom" to store a block of data in a non-volatile manner. But I found the STM provided eeprom.c/h utility very cumbersome and restrictive, storing data as individual 16 bit variables.

So I designed my own FLASH/eeprom utility that can easily store blocks of any size.

I chose to use the last 2KByte page of a 256KByte STMF303VCT6 chip starting at address 0x0803F800. I made a simple "cell" data structure thus:

#define USER_FLASH_STRUCT_SIZE 128
#define USER_FLASH_DATA_ARRAY_SIZE (USER_FLASH_STRUCT_SIZE-4)
#define USERFLASH_STRUCTURE_KEY  0xAABBCCDD

typedef struct
{
   U32 UserFlashKey;
   U8  Data[USER_FLASH_DATA_ARRAY_SIZE];
} UserFlashStruct;

The UserFlashKey field is filled with a fixed value, above I use 0xAABBCCDD, but it can be any value, other than 0xFFFFFFFF, you like.

When I want to write a block of data, I search through the the "cells" on the FLASH page sequentially until I find a UserFlashKey value of 0xFFFFFFFF following a previous cell's UserFlashKey value of 0xAABBCCDD. That means the current cell has not yet been written to since the last page erase and can be used to store the new block of user data. If there is no cell containing a UserFlashKey value of 0xAABBCCDD then no writes have been performed and we start at the beginning of the FLASH page.

First, I write the value 0xAABBCCDD to the UserFlashKey field first to indicate the cell has now been used, then write the Data payload to the rest of the "cell", word by word.

This process continues until we have filled the flash page up. When I next do a write, I determine that there are no more empty cells left, so I copy the last (i.e. highest address) cell to RAM, erase the page, then write the new cell's worth of data to the start of the user flash page. If that write fails, I attempt to write back the last cell's content held in RAM to the first cell's address. If that fails also, then we have lost the stored data.

Reading is done in a similar manner - i.e. find the last "cell" to be written and copy that cell's contents to the user buffer.

I have attached a ZIP file here containing two files - userflash.c and userflash.h.

The code can be easily modified for other cell sizes and chips. If you increase the cell size,
then fewer cells can be accommodated in the FLASH page before it has to be erased and re-used again so the lifetime of that page would be reduced.

It could also be adapted to use a larger number of FLASH pages to increase the wear-levelling effect.

This technique will take much more FLASH space with larger chips that have larger page sizes such as 64KBytes since the minimum erase size is one page so you lose that minimum amount for the application FLASH space.

Attachments

Outcomes