EEMEM

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

Could you please help me to understand the usage of EEMEM in GCC compiler ?

I try to understand why when I compile the above project and program uC without touch EEPROM , the code seems to NOT write initial key sequence as mentioned inside code:

 

unsigned char EEMEM code1 = 1;
unsigned char EEMEM code2 = 2;
unsigned char EEMEM code3 = 3;
unsigned char EEMEM code4 = 4;

   The code is here: (http://jumptuck.com/2010/08/01/g...).

 

 

Some colleges help me a lot but it is still not clear for me ...  (https://www.avrfreaks.net/forum/...)

 

In other words I would like for the code to write itself the initial code sequence in EEPROM when it starts.

 

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

the EEMEM keyword will create a separate hex file with an ".eep" extension, this file will need to be programmed into the chip along with the flash memory ".hex" file.

The ".eep" file contains the values for the eeprom.

So it will take two load operations to get what you want, but pretty easy once you've done it. 

 

Jim

 

 

 

 

 

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

I already told you in the other thread. 

 

The lines above create some data in the .eeprom section.

D:\test\GccApplication1\GccApplication1\Debug>avr-objdump -s -j .eeprom GccApplication1.elf

GccApplication1.elf:     file format elf32-avr

Contents of section .eeprom:
 810000 04030201                             ....

You can see 04 03 02 01 in that (and, yes, it just happens to have been placed "backwards"). The above has been created withing the ELF file for the project.

 

At build time an avr-objcopy command is run to extract .eeprom from the ELF file and create an EEP file. You can see that:

D:\test\GccApplication1\GccApplication1\Debug>type GccApplication1.eep
:0400000004030201F2
:00000001FF

The key part in that is:

:04 0000 00 04030201 F2

So this is a 4 byte record at address 0000 that is type 00 (data) and the data bytes are 04 03 02 01 with a checksum of F2.

 

So all you have to do is when you use your programmer to load GccApplication.hex into the flash of the AVR you also use you programmer to load GccApplication.epp into the EEPROM of you AVR. That means that EEPROM location 0000 will contain 04, location 0001 will contains 03 and so on.

 

When you AVR code does something like:

byyte = eeprom_read_byte(&code3);

then because "code3" actually has the EEPROM address 0001 this will read whatever is in EEPROM location 0001 and because of the .eep file you programmed into it then it will find 03 there.

 

As you were told in the other thread do set the EESAVE fuse active. By default when you put new code into the AVR the programming starts with a "Chip Erase" and, unless told otherwise, chip erase means "wipe flash and EEPROM". So if you have not set EESAVE you will find that you have to program in both the .hex file and the .eep file every time. If you have set EESAVE then when "chip erase" is performed it will not wipe the EEPROM and the 04 03 02 01 that is already there will remain.

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

I understand most of them from the previous thread.

The problem is not with what way can leave the old contents in EEPROM. I would like from the code , to (over)write those contents of 1234 to EEPROM every time that uC "boots" WITHOUT the need to write EEPROM data at all !

 

As verification, I need after programming only the flash, to just read EEPROM and its contents to be the initial code sequence. How can I do that ?

 

 

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

bnsavr wrote:

I understand most of them from the previous thread.

The problem is not the procedure to keep intact EEPROM contents. I would like from the code , to (over)write those contents of 1234 to EEPROM every time that uC "boots" WITHOUT the need to write EEPROM data at all !

 

As verification, I need after programming only the flash, to just read EEPROM and its contents to be the initial code sequence. How can I do that ?

 

 

Last Edited: Mon. Nov 11, 2019 - 02:31 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ah OK. Then what you would usually do is have some kind of "validity cookie". So you might have something like:

unsigned char EEMEM code1 = 1;
unsigned char EEMEM code2 = 2;
unsigned char EEMEM code3 = 3;
unsigned char EEMEM code4 = 4;
unsigned char EEMEM valid = 0x5A;


int main(void) {
   if (eeprom_read_byte(&valid) != 0x5A) {
       // either EEP file has not been programmed in or EEPROM is otherwise wipde
       eeprom_update_byte(&code1, 1);
       eeprom_update_byte(&code2, 2);
       eeprom_update_byte(&code3, 3);
       eeprom_update_byte(&code4, 4);
       eeprom_update_byte(&valid, 0x5A);
   }
   // rest of program...
}

So each time this AVR is turned on and main() begins to run it will read the "valid" byte to check to see if EEPROM already holds something sensible. If the EEPROM has been erased and not programmed then all locations will hold 0xFF). If it read the "valid" location and does not find 0x5A there then the cod can assume that what is in the other 4 locations is not valid. So it sets those locations to the default 1,2,3,4 and the valid marker (cookie) to be 0x5A.

 

Of course, somewhere in the code you might offer the facility for the user to change the current PIN but as long as you ensure that "valid" keeps (or is written again) with 0x5A then at next power on the test:

   if (eeprom_read_byte(&valid) != 0x5A) {

will find 0x5A in that location so it won't be tempted to write the other bytes to 1,2,3,4

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

From your other thread,  I suggested:

 

In AS7.0 Project->Properties->Tool:

select Programmer e.g. ATMEL-ICE, STK500, ...

select Programmer settings i.e. [Erase entire chip] and uncheck [Preserve EEPROM]

 

This ensures that the EEPROM gets programmed with your EEMEM values.

 

If you are unsure about programmers, settings, ... tell us what hardware you have.   And whether you use AS7.0,  AS6.2, ....

 

David.

The traditional behaviour for AVR projects is to program Flash memory with the project.hex file and EEPROM memory with the project.eep file.

Flash and EEPROM are erased every time you program.

This means unused locations in Flash memory are 0xFFFF and unused locations in EEPROM memory are 0xFF.

 

This works fine for EEMEM variables e.g. your GarageLock data.

 

But it is not convenient for programs that have initialised data in EEMEM e.g. your "key" and non-volatile data in EEMEM e.g. calibration data,  names, addresses, ...

 

It is handy to make a "fresh start" every time you program the chip with initialised data.

But you would lose the important calibration, names, addresses, ... that you had entered from previous runtimes.

 

If you use the EESAVE fuse,  the EEPROM is not erased.   Initialised data is just written over the previous contents.

My EEP file looks like this (my key is 5 6 3 4):

:0400000004030605EA
:00000001FF

Only those 4 bytes are re-programmed.

 

It seems that the [Preserve EEPROM] box prevents the EEPROM being programmed at all.

In other words.  AS7.0 is trying to be too clever.

 

I don't think you will have this problem with any other IDE.

I seldom used initialised EEMEM.   Like Cliff,   I use a magic sequence to detect virginity.   And initialise at runtime if required.

 

David.

 

p.s.  can readers look at their typical AS7.0 projects.

What is the default state of your [Preserve EEPROM] box ?

Last Edited: Mon. Nov 11, 2019 - 03:25 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Clawson , I see... In other words this is nothing else than a flag. Ang code just see if us is set or not in a given time...

Last Edited: Mon. Nov 11, 2019 - 03:35 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Yup, it's one extra thing stored as a flag in the EEPROM basically to say whether what is found in the EEPROM can be trusted or not. Some folks might actually group this all together as something like:

typedef struct {
  uint8_t code[4];
  uint16_t validity_cookie;
} eeLayout_t;

eeLayout_t eeVars EEMEM;

int main(void) {
    if (eeprom_read_word(&eeVars.validity_cookie) != 0x55AA) {
        eeLayout_t eeCopy;

        eeCopy.code[0] = 1;
        eecopy.code[1] = 2;
        eeCopy.code[2] = 3;
        eecopy.code[3] = 4;
        eeCopy.validity_cookie = 0x55AA;

        eeprom_update_block(&eeVars, &eeCopy, sizeof(eeLayout));
    }
    // etc.
}

I like "objects" that group together all the things that are connected in some way so the eeLayout is nice as it puts the 4 byte code and also my vailidity value all grouped together. It also just need one write (update) to write everything in one go. My read/check code shows that I can also access single items or groups from within the structure too. So read the 4 byte code I might later do something like:

uint8_t code[4];

eeprom_read_block(code, &eeVars.code, 4);

to read all 4 bytes in one go into a four byte array in RAM called code[].

 

PS forgot to say that if I was going to use an EEP file then:

eeLayout_t eeVars EEMEM;

could just as easily be:

eeLayout_t eeVars EEMEM = {
    { 1, 2, 3, 4},
    0x55AA
};

to give initial values that would create the .eep contents.

Last Edited: Mon. Nov 11, 2019 - 03:52 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Guys, its working !

Last Edited: Tue. Nov 12, 2019 - 02:09 PM