struct{} in EEPROM?

Go To Last Post
2 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

just finished reading the docs I found on using the EEPROM for non-volatile storage.

If I understood everything right, the EEPROM can hold any kind of data, as long as it is read or written byte by byte. For storing a float value, this would mean using a union and an EEPROM variable like:

uint8_t  EEMEM nvol_foobar[4] = {0x00000000};

union
{
	float	real;
	uint8_t	bytes[4];
} foobar;

and then reading or writing it:

// Read
eeprom_read_block((void*) &tmpstr, (const void*) &nvol_foobar, 4);

// Write
eeprom_write_block ((const void*) &foobar.real, (void*) &nvol_foobar, 4);

Now I´ve got a few values that are logically grouped together. Would it be possible to define a struct for the EEPROM?:

struct
{
	uint8_t  EEMEM foo1[4] = {0x00000000};
	uint8_t  EEMEM foo2[4] = {0x00000000};
	uint8_t  EEMEM foo3[4] = {0x00000000};
} nvol_foobar

and then reading or writing it:

// Read
eeprom_read_block((void*) &tmpstr, (const void*) &nvol_foobar.foo1, 4);

// Write
eeprom_write_block ((const void*) &foobar.real, (void*) &nvol_foobar.foo2, 4);

It would be possible to keep all EEPROM values separate, but I think grouping them in a struct seems a better way of representing the logic connection between the values and would enhance the maintainability of the code.

Ingo

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You don't need a union for the float when storing. Since the write and read block routines use a void pointer, it does not care what the data it is copying is. Specifying the "sizeof(float)" as the size should be enough:

// Read
eeprom_read_block((void*)&LocalFloatValue, (const void*) &EEPROMFloatValue, sizeof(float));

// Write
eeprom_write_block ((const void*)&LocalFloatValue, (void*) &EEPROMFloatValue, sizeof(float));

As for using a struct, that's perfectly fine. You can either copy out the elements of the struct as you need them:

struct {
uint8_t SomeByte1;
uint8_t SomeByte2;
} EEVars EEMEM;

eeprom_read_byte(&EEVars.SomeByte1);

Or the entire struct into a local copy:

typedef struct {
uint8_t SomeByte1;
uint8_t SomeByte2;
} EEVarsType;

EEVarsType EEPROMcopy EEMEM;
EEVarsType SRAMcopy;

// Read
eeprom_read_block((void*)&SRAMcopy, (const void*) &EEPROMcopy, sizeof(EEPROMcopy));

// Write
eeprom_write_block ((const void*)&SRAMcopy, (void*) &EEPROMcopy, sizeof(EEPROMcopy));

It's all just bytes to the block routines - it doesn't care what it is copying. By specifying "sizeof(EEPROMcopy)" in the above example as the copy size, you ensure that the entire struct is copied to and from the EEPROM memory despite changes to the size of the struct - so adding more variables later won't require extensive code changes.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!