0
\$\begingroup\$

I use stm32f030 and I use st eeprom emulation library. I want to know how many variables I can save in eeprom? I have 48 variables and in this case, I have to create 48 pages? Is it possible to save more than one variable in one page? Or I have to save each variable in one page? After writing and reading for several times, sometimes the memory loss the defined variables. This is the code that I use for saving my variables.

FLASH_Unlock();

EE_Init();  


for(k=0;k<=3;k++){ data = pass_2[k]; EE_WriteVariable( ++i , data ); }   

for(k=0;k<=3;k++){ data = pass_3[k]; EE_WriteVariable( ++i , data ); }  

for(k=0;k<=3;k++){ data = pass_4[k]; EE_WriteVariable( ++i , data ); } 

for(k=0;k<=24;k++){ data = z1[k]; EE_WriteVariable( ++i , data ); }  

for(k=0;k<=2;k++){ data = z2[k]; EE_WriteVariable( ++i , data ); }  

for(k=1;k<=2;k++){ data = z3[k] ; EE_WriteVariable( ++i , data ); } 

for(k=0;k<=10;k++){ data = phone_number[k] ; EE_WriteVariable( ++i , data ); }

for(k=0;k<=24;k++){ data = z4[k] ; EE_WriteVariable( ++i , data ); }

for(k=0;k<=24;k++){ data = z5[k] ; EE_WriteVariable( ++i , data ); }

EE_WriteVariable( ++i , relay );

EE_WriteVariable( ++i , counter ); 

EE_WriteVariable( ++i , zs); 

EE_WriteVariable( ++i , check); 

if(lcd_HD_786543 == 22){ flash_ch = 457;    }

EE_WriteVariable( ++i , flash_ch );

    
FLASH_Lock();   
\$\endgroup\$
2
  • \$\begingroup\$ Please update your question and show your code. \$\endgroup\$ – Tagli May 11 at 11:59
  • \$\begingroup\$ @Tagli: I updated question and add the code. \$\endgroup\$ – Hamed P May 12 at 5:39
2
\$\begingroup\$

No, AFAIK the algorithm needs just 2 pages. Number of variables (keys) is irrelevant. You just need to define separate keys for your variables. Remember, each 2-byte record needs a 2-byte key, and they don't take any space unless you record them. Of course I'm assuming that your variables are at most 2-byte long.

I can't remember if the library provides a solution for longer data blocks. I actually ended up writing my own EEPROM emulation library based on the page switching method mentioned on that application note, to support arbitrary sized data blocks.

\$\endgroup\$
6
  • \$\begingroup\$ My variables are characters like 'e' or 'd'. I use this for writing on eeprom. EE_WriteVariable( 1 , data ). What does this mean by your explanation? It writes data on page 1? If I want to write 'e' and after that write 'd', what would be the address in that command? \$\endgroup\$ – Hamed P May 10 at 6:19
  • 2
    \$\begingroup\$ 1 mentioned in that function is not an address or page. Application Note (AN) calls is virtual address, but I would rather call it a key. All the records, even the ones having different keys end up in the same page unless the page is full. When the page is full, the most recent records are moved to a new page and the old one is erased/cleared. When there are multiple records with the same key, only the latest one is used. This is the main idea, which allows you to update the records. \$\endgroup\$ – Tagli May 10 at 6:26
  • \$\begingroup\$ Ok by minding that each 2-byte record needs a 2-byte key, for recording for example 'e' I will write EE_WriteVariable( 1 , 'e' ) and for recording 'd', I have to write EE_WriteVariable( 5 , 'd')? I got a bit confused \$\endgroup\$ – Hamed P May 10 at 6:34
  • 1
    \$\begingroup\$ No, the first parameter isn't an address. Maybe it's better to think that it's a name rather than a number, like "Record 1". You can overwrite any record using the same name (I still prefer to call them keys). When you try to access them with the same name/key, you get only the latest one. So if you need 48 records, just name them from 1 to 48. When you want to update your variables, again use the same numbers, from 1 to 48. \$\endgroup\$ – Tagli May 10 at 6:42
  • \$\begingroup\$ @Tgli : Now I write 48 variables on eeprom and after some reset, I faced data loss! I mean sometimes data on eeprom clears and I have to reset several times. What is problem? or what can I do for preventing this \$\endgroup\$ – Hamed P May 11 at 11:56
2
\$\begingroup\$

Unfortunately, the EEPROM library documentation is very strange. It goes into great details about the implementation but fails short regarding the use of the library.

As Tagli has already mentioned, the main idea is that it is a key/value store. So a simple usage could look like so:

define NB_OF_VAR 3

...

#define EE_KEY_COLOR       0x0100
#define EE_KEY_BRIGHTNESS  0x0102
#define EE_KEY_MODE        0x0200

uint16_t VirtAddVarTab[NB_OF_VAR] = { EE_KEY_COLOR, EE_KEY_BRIGHTNESS, EE_KEY_MODE };

uint16_t color;
uint16_t brightness;
uint16_t mode;

...
void readSettings(void) {
    EE_ReadVariable(EE_KEY_COLOR, &color);
    EE_ReadVariable(EE_KEY_BRIGHTNESS, &brightness);
    EE_ReadVariable(EE_KEY_MODE , &mode);
}

void writeSettings(void) {
    EE_WriteVariable(EE_KEY_COLOR, color);
    EE_WriteVariable(EE_KEY_BRIGHTNESS, brightness);
    EE_WriteVariable(EE_KEY_MODE , mode);
}

Your use case is more advanced: you want to store bigger data structures instead of a bunch of 16 bit values. With STM's library, you will need to split it into units of 16 bit, e.g.:

typedef struct {
    char name[10];
    uint32_t z1;
    uint32_t z2;
} settings_t __attribute__((packed));

define NB_OF_VAR (sizeof(settings_t)/2)

...

uint16_t VirtAddVarTab[NB_OF_VAR] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };

settings_t settings;

...
void readSettings(void) {
    uint16_t* p = (uint16_t*)&settings;
    for (int i = 0; i < NB_OF_VAR; i++, p++)
        EE_ReadVariable(i, p);
}

void writeSettings(void) {
    uint16_t* p = (uint16_t*)&settings;
    for (int i = 0; i < NB_OF_VAR; i++, p++)
        EE_WriteVariable(i, *p);
}

It's not a very idiomatic use of the library, most obvious by how the VirtAddVarTab is filled. But it should work. Note that VirtAddVarTab needs to contain all keys (called virtual addresses in the documentation). Otherwise you lose data when the data needs to be migrated to a new page.

Each key/value pair takes up 4 bytes and each page has a marker at the start that takes up another 4 bytes. So given a flash page size of 128 bytes (if I'm not mistaken), you can fit 31 pairs or 62 bytes of raw data on a flash page. With STM's library, you cannot change the number of flash pages. It's always 2.

Update

The flash page size is 1024 bytes (thanks for Tagli for pointing it out). So you can store 255 key/value pairs or 510 bytes of raw data.

\$\endgroup\$
1
  • \$\begingroup\$ +1 for the detailed answer. Flash page size is 1024 bytes in STM32F030 series. \$\endgroup\$ – Tagli May 12 at 10:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.