I am storing a lot of variables in EEPROM. My issue is : how do I get to them in an elegant and painless way?
For instance, handling regular variables in RAM is transparent to me because the compiler takes care of loading them from memory and storing them back. I do not need to know their address. Unfortunately, that is not the case in EEPROM.
Currently, here is how I proceed. I have an eeprom_data.h file in which I store stuff like this:
#define START_OF_EEPROM_DATA (0x00)
#define ADDRESS_OF_MYVAR_1 START_OF_EEPROM_DATA /* uint8_*/
#define ADDRESS_OF_MYVAR_2 (ADDRESS_OF_MYVAR_1 + sozeof(uint8_t)) /* uint32_t */
#define ADDRESS_OF_MYVAR_3 (ADDRESS_OF_MYVAR_2 + sozeof(uint32_t)) /* uint8_t */
#define ADDRESS_OF_MYVAR_4 (ADDRESS_OF_MYVAR_3 + sozeof(uint8_t)) /* float32_t */
Then, I use function such as :
uint8_t myvar3 = read_uint8_from_eeprom(ADDRESS_OF_MYVAR_3);
float myvar4 = read_float_from_eeprom(ADDRESS_OF_MYVAR_4);
How do you proceed? What's the best way of efficiently addressing the variables stored in EEPROM? Can the compiler do that for me?
Why not keep all your EEPROM data in a structure, and just read and write the whole thing?
Because I really have a lot of variables (currently 131) and occupy 321 bytes of memory. Reading the data structure would not only consume lots of memory (I guess would have to use a global, because putting a large struct like that on the stack frame…) but updating it would take ages.
That's why I use #define directive to store their address: they don't take RAM space. Only flash. Each time they're used.
Reading the data structure would not only consume lots of memory
Memory that you were going to use for the variables anyway. . .
As AWOL says, you should make all the variables you want to write to EEPROM members of a struct, and declare one global instance of that struct instead of declaring all the variables.
If you sometimes want to save just some bits of the struct to EEPROM, there is a standard C macro called 'offsetof' that you can use to get the offset of the start of a field within a struct.
The firmware is an abstract program, which purpose is not defined when programmed, but when used.
Imagine the EEPROM is divided into 47 groups of variables (some contain a one byte variable). Only a few of these groups will be used on a given device. Which are these groups depends on the intent of the user.
As a result:
– Using a structure is indeed a waste of memory.
– I cannot use a smaller structure, because I do not know which groups will be used. And dynamically mapping the EEPROM would require more code (flash space, which is almost full on my board), in addition to slow me further down when coding.
So struct are not an option unless there is a way of getting the offset of a variable in a struct (does the compiler do that?). In this case, I can declare the struct, without allocating it, get the offset, and fetch it in memory. Is that even possible?
Thank you so much !
Checking the macro in your message, I was lead to __builtin_offsetof, which is perfect. I can use it on the structure without actually allocating it on memory. That is perfect for me.