I am trying to port a code base from iar to avr-gcc. Amongst other things that have to replaced, the iar eeprom memory attribute __eeprom has to replaced with a avr-gcc friendly attribute. AFAIK the replacement for that is EEMEM, but the usage differs and I am not able to figure out how to replace __eeprom in the cleanest manner.
../src/myfunc.h:35:46: error: section attribute not allowed for 'src'
UBYTE *strcpye(UBYTE *dest, UBYTE EEMEM *src);
This error is not limited to pointers, but to all variables in general. IMO the usage of EEMEM is correct, where am I going wrong?
In the avr-gcc toolchain, avr-libc defines macro EEMEM
in avr/eeprom.h
:
#define EEMEM __attribute__((section(".eeprom")))
This means it's just an attribute that determines the section in which an object with this attribute will be located. In particular, EEMEM
only makes sense for variables in static storage. Moreover, accesses to objects located in EEMEM
have to be done by hand using functions / macros supplied by avr/eeprom.h
like
void eeprom_read_block (void *dst, const void *src, size_t n);
void eeprom_write_byte (uint8_t *p, uint8_t value);
void eeprom_update_word (uint16_t *p, uint16_t value);
etc. Also notice that EEMEM
is just an attribute and not a qualifier (like __flash
for example). This means that even though you can tag a pointer (target) using attributes, that won't change the access in any way. To be more specific, any access through a pointer that's attributed EEMEM
will be to RAM and not to eeprom.
In your case, the prototype of strcpye
would read
char* strcpye (char *dest, const char *src);
and the implementation of that function would apply eeprom_read_byte
on src++
and write to dest++
until it reads a terminal \0
. Notice that you might need an explicit pointer cast as eeprom_read_byte
expects [const] uint8_t*
, and that char
, signed char
and unsigned char
are 3 distinct types in C.