I'm working on an embedded project. I'm trying to use the GNU linker to layout some variables stored in a external eeprom. I do this by assigning the eeprom variable with
int __attribute__ ((section (".eeprom"))) eeprom_var1;
I've will also to define initialized variables for the eeprom, ie like this:
int __attribute__ ((section (".eeprom"))) eeprom_var2 = 0x42;
The idea is then; upon initialization of the eeprom the initialized variables copied from somewhere in the .text section to the eeprom by the running application, just like the initializing the data section. Obviously the eeprom variables cannot be read/written but must be accessed though functions like:
eeprom_read(data, &eeprom_var,sizeof(eeprom_var)).
So far so good,
Now I want to initialize an eeprom variable with the pointer of another variable:
unsigned long long __attribute__ ((section (".eeprom"))) eeprom_var1 = 0x42;
unsigned short __attribute__ ((section (".eeprom"))) eeprom_var2 = (unsigned short )&eeprom_var1;
Note that the eeprom uses a 16bit address space
But this gives the following error
foo.c:4:1: error: initializer element is not constant
unsigned short __attribute__ ((section (".eeprom"))) eeprom_var2 = (unsigned short )&eeprom_var1;
^
This is because the cast to (unsigned short) is read as an operation as an initializer, which is not allowed in C. In C++ however the above expression is ok.
Can any one think of way to get around the error above?
/Anders
const type
.type* const
(constant pointer to non-constant data) orconst type* const
(constant pointer to constant data).This seems to be the true source of your problem. And of course, once they are declared as const you shouldn't cast away the const-ness.
Also, if it is on-chip eeprom, is there a reason why you can't access the memory cells directly? On most systems you are able to do this, although access times may be slower than the equivalent access to a RAM variable.
As a side note, casting to
uint16_t
(or unsigned short) will only give you the 16 least significant bits on a little endian machine. The code isn't portable to big endian. Portable code would be((uint32_t)pointer >> 16)
.