Reading EE value directly into multibyte-variables

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

Hi guys,

 

I'm trying to figure out, how to read EEprom values directly into variables, which are dedicated to specific cells of the EE.
This is for a universal way to read all stored values in the EE into dedicated variables, e.g. at the start of main, no matter what types (uint8_t, uint16_t, uint32_t) they are.

I remember, I've seen such a way before which worked fine, but I think there is something missing here....

 

An example, to make more clear, what I'm trying to do:
 

The variable _length should have 2 byte (= uint16_t)

Now I would define:

uint8_t _lenght[2];  // variable
and
uint8_t EEval[2];   // values of a single EE-cell

The values for _length[0] and _length[1] are stored in the EE[50] (=HB) and EE[51] (=LB).

and defining
uint8_t  *VarName_ptr;  // pointer to a variables name

and assigning the VarName_ptr to the variable:

VarName_ptr = _lenght;  // pointer to the variable _length

EEval[0] = eeprom_read_byte((uint8_t*) 50);  // value = 0x80 (=HB)
EEval[1] = eeprom_read_byte((uint8_t*) 51);  // value = 0xFB (=LB)

now assigning

VarName_ptr [0] = EEval[0];
VarName_ptr [1] = EEval[1];

I'd like to see _length now as 0x80FB, so I can 'use' it as uint16_t.
But the value shows up as 0x8FA ,using
sprintf (StrDisplay, "Length: %x", _length);
lcd_sendString(StrDisplay);

 

Any ideas, what I'm doing wrong?

Thanks!
BEXX

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

Eeprom-read-block

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

"pointer to a variables name" is conceptually valid. Variable names are not objects in the executing program.

 

Don't try to alias it like this; it's possible to make it work, but it's not portable or correct, and the compiler can optimize it away. Instead, try something like:

 

uint16_t length;
length = (eeprom_read_byte((uint8_t *) 50) << 8) + eeprom_read_byte((uint8_t *) 51);

Note also that the EEVal array is completely unnecessary; there's no reason to make a separate array, and then copy from one array to another.

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

If you are storing a uint16_t then why aren't you simply using eeprom_update_word()?

 

Also there's something very suspicious in your code above where you assign "_lenght" (which is presumably really length?) to a pointer. Pointers are designed to store (usually 16 bit) memory addresses not numeric values.

 

Also don't use a leading underscore in your own symbol names. Because C does not have "namespace" like C++ does then the compiler developers try to avoid namespace pollution by reserving symbols with one leading underscore for use by the C library and they use two underscores for symbols in the namespace of the actual compiler. So programmers in C should not use either one or two leading underscore in their own symbol names. 

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

I usually put all the EEprom variables in a structure and use eeprom_read_block() to read and eeprom_update_block() to write.

Do you have a specific reason to use absolute EEprom addresses?

 

Also: try to simplify our code. You are trying to do several things at once

- Writing from EEprom.

- Combining bytes into bigger variables.

- Juggling with pointers.

 

You say you want a value to be 0xFB, but it reads from EEprom as 0xFA.

The code where this var is written to EEprom is however not shown.

Maybe your comment is wrong and 0xFB is the value actually in EEprom.

 

"length" is an uint8_t and VarName_ptr is a pointer to uint8_t, but you want to use them vor 16 bit variables?

 

It's much simpler to just put all your variables in a structure and use the EEmem block functions.

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

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

BEXX wrote:
This is for a universal way to read all stored values in the EE into dedicated variables, e.g. at the start of main, ...

 

Interesting in itself.

 

I do have a couple apps over the years that use an SRAM copy of an EEPROM table.  But I'd consider that the exceptional case -- I want to do a lookup inside of an ISR and don't want to risk that an in-process EEPROM write might hold up my ISR for milliseconds.

 

Now let's talk about the "all".  Many/most AVR8 models have an internal EEPROM at half the internal SRAM size.  Do you really intend to "burn" up to half the SRAM space "just because"?  While an EEPROM access does indeed take longer than a 2-cycle LDS, occasional access of system options and similar parameters shouldn't be onerous.

 

Having a large block of "saved state" brings up how you can win the race at power loss to save the state.  And how catastrophic unexpected resets might be.

 

I might suggest a structure of the critical save-state parameters just to make save/fetch a bit more straightforward?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

...many thanks for all your answers!

It's really helpful to get a different view and to learn something.

I now will need to think it over, to find a resonable solution for my needs.