3

After long time investigation, I could not find proper information about #define EEMEM __attribute__((section('.eeprom'))) macro on eeprom.h header file.

I want to declare variable exactly at address 0x0010 on Atmega128 EEPROM. Because, when I use (example) uint8_t EEMEM Variable = value, it saves value at 0x0000 address automatically, it is being deleted sometimes (I think there is some mistake on hardware.) I tried with different hardware, but same result.

In Codevision for AVR, you can use as: eeprom unsigned char Variable@0x0010; to declare variable at 0x0010 address of EEPROM.

My question: "Is there are any alternatives to daclare variable at 0x0010 address on AVRStudio 6?"

Kozmotronik
  • 107
  • 5
Mamurbek
  • 35
  • 5

2 Answers2

1

You can read/write values in specific eeprom address using the following code:
(I use macros but you can use the functions given in eeprom.h directly if you prefer)

#include <avr/eeprom.h>

// macro for eeprom access  
#define read_eeprom_byte(address) eeprom_read_byte ((const uint8_t*)address)
#define write_eeprom_byte(address,value) eeprom_write_byte ((uint8_t*)address,(uint8_t)value)
#define read_eeprom_word(address) eeprom_read_word ((const uint16_t*)address)
#define write_eeprom_word(address,value) eeprom_write_word ((uint16_t*)address,(uint16_t)value)
#define read_eeprom_dword(address) eeprom_read_dword ((const uint32_t*)address)
#define write_eeprom_dword(address,value) eeprom_write_dword ((uint32_t*)address,(uint32_t)value)
#define read_eeprom_float(address) eeprom_read_float ((const float *)address)
#define write_eeprom_float(address,value) eeprom_write_float ((float*)address,(float)value)
#define read_eeprom_array(address,value_p,length) eeprom_read_block ((void *)value_p, (const void *)address, length)
#define write_eeprom_array(address,value_p,length) eeprom_write_block ((const void *)value_p, (void *)address, length)

uint8_t my_byte;
uint16_t my_word;
uint32_t my_dword;
float my_float;
char my_text[10]={"123456789\0"};

//--------------- code inside main-----------------
// these will be written at runtime (and stored in first run), data will not be included in the eep file
write_eeprom_byte(1,0x0A);        // write in eeprom address 1 the value 0x0A
write_eeprom_word(3,0x0AAA);          // write in eeprom starting from address 3 the value 0x0AAA
write_eeprom_dword(10,0x0AAAAAAA);// write in eeprom starting from address 10 the value 0x0AAAAAAA
write_eeprom_float(5,0.123456);// write in eeprom starting from address 5 the value 0.123456 , note it will occupy 4 bytes in eeprom 5,6,7,8
write_eeprom_array(10,my_text,8);    // write in eeprom starting from address 10 the 8 first characters of my_text array


// and you can read them using
my_byte=read_eeprom_byte(1);            
my_word=read_eeprom_word(3);        
my_dword=read_eeprom_dword(10);
my_float=read_eeprom_float(5);
read_eeprom_array(10,my_text,5); // read to my_text array 5 char starting from eeprom address 10

I have not included the eeprom update functions but they work in a similar way

alexan_e
  • 11,070
  • 1
  • 28
  • 62
0

There are a couple of options. The first is to note that EEMEM just pre-allocates variables into the EEPROM memory space, and you can just as easily use the actual memory addresses in the various eeprom_ api functions. So you could create a table of #define constants for the variables you require and access them this way. The only real disadvantage is that you need to keep track of how each variable is allocated, but as soon as you require fixed allocations then you'll have to do this anyway.

If you only require part of the memory to have fixed allocation and the rest you want the compiler to sort out, you can create a new linker section, for example, called .eepromfixed. You could allocate say the first 256 bytes of EEPROM to this section and use it for manually allocated variables (as described above), and then use the regular EEPROM section for anything else.

Jon
  • 4,894
  • 13
  • 20