I use st eeprom library to save my variables. When I save a single variable, I do not have any problem. I can save it, refresh it and after disconnecting the power, I can read that variable. Now I want to save three different variables in three different pages, when I want to read them, I see the latest value in all of them. With this code I save the variables:
HAL_FLASH_Unlock();
EE_Init();
EE_WriteVariable(VirtAddVarTab[0], 10);
EE_WriteVariable(VirtAddVarTab[1], 20);
EE_WriteVariable(VirtAddVarTab[2], 30);
HAL_Delay(10);
EE_ReadVariable(VirtAddVarTab[0], &VarDataTab[0]);
EE_ReadVariable(VirtAddVarTab[1], &VarDataTab[1]);
EE_ReadVariable(VirtAddVarTab[2], &VarDataTab[2]);
HAL_FLASH_Lock();
After programing this code, I program this one:
HAL_FLASH_Unlock();
EE_Init();
EE_ReadVariable(VirtAddVarTab[0], &VarDataTab[0]);
EE_ReadVariable(VirtAddVarTab[1], &VarDataTab[1]);
EE_ReadVariable(VirtAddVarTab[2], &VarDataTab[2]);
HAL_FLASH_Lock();
And I see "30" in all of the memory them instead of 10,20,30
What is my problem?
page addresses :
#define ADDR_FLASH_PAGE_0 ((uint32_t)0x08000800) /* Base @ of Page 0, 1 Kbytes *///0x08000000
#define ADDR_FLASH_PAGE_1 ((uint32_t)0x08001000) /* Base @ of Page 1, 1 Kbytes *///0x08000400
#define ADDR_FLASH_PAGE_2 ((uint32_t)0x08001800) /* Base @ of Page 2, 1 Kbytes *///0x08000800
#define ADDR_FLASH_PAGE_3 ((uint32_t)0x08002000) /* Base @ of Page 3, 1 Kbytes *///0x08000C00
#define ADDR_FLASH_PAGE_4 ((uint32_t)0x08002800) /* Base @ of Page 4, 1 Kbytes *///0x08001000
#define ADDR_FLASH_PAGE_5 ((uint32_t)0x08003000) /* Base @ of Page 5, 1 Kbytes *///0x08001400
#define ADDR_FLASH_PAGE_6 ((uint32_t)0x08003800) /* Base @ of Page 6, 1 Kbytes *///0x08001800
#define ADDR_FLASH_PAGE_7 ((uint32_t)0x08004000) /* Base @ of Page 7, 1 Kbytes *///0x08001C00
#define ADDR_FLASH_PAGE_8 ((uint32_t)0x08004800) /* Base @ of Page 8, 1 Kbytes *///0x08002000
#define ADDR_FLASH_PAGE_9 ((uint32_t)0x08005000) /* Base @ of Page 9, 1 Kbytes *///0x08002400
#define ADDR_FLASH_PAGE_10 ((uint32_t)0x08005800) /* Base @ of Page 10, 1 Kbytes *///0x08002800
And I have two IROM
IROM1 start address is 0x8000000 and its size is 0x400
IROM2 start address is 0x8000800 and its size is 0xF800
I define these in the beginning of the program :
uint16_t VirtAddVarTab[20];
uint16_t VarDataTab[20];
I did not initialize it. Do you mean I put for example 0 in the start and after that I use them?
Best Answer
STM's pseudo EEPROM library offers an interface to read and write key/value pairs. Keys are
uint16_t
values. The arrayVirtAddVarTab
is supposed to contain all possible keys.Your code does not explicitly initialize
VirtAddVarTab
. So all keys are 0. Therefore, the code always writes to and reads from key 0.To fix it, initialize
VirtAddVarTab
, e.g.:While
VirtAddVarTab
is needed, you don't need to use it forEE_WriteVariable()
andEE_ReadVariable()
. (I assume you have copied it from STM's strange example code.)An improved approach would be:
VirtAddVarTab
is required when a flash page has filled up and the active key/value pairs have to be transferred to another flash page. It's an unfortunate design decision by STM as it results in a mutual dependency between the project code and the library code.STM's approach for the pseudo EEPROM is robust: it reduces flash wear and can recover even if power failed during write. However, the API is more complex than necessary, and the documentation – while covering the implementation in detail – insufficiently describes the usage.