New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EEMEM variable initialization not performed #1318

Open
mikaelpatel opened this Issue Mar 14, 2013 · 8 comments

Comments

8 participants
@mikaelpatel

mikaelpatel commented Mar 14, 2013

A practical method of allocating and initiating a variable in eeprom is to use the AVR EEMEM attribute (short form for a GCC function attribute). Unfortunately the initialization gets lost in the build/upload process in Arduino.

uint8_t foo EEMEM = 42;

eeprom_read_byte((const uint8_t*) &foo); // will return 255 and not 42

Cheers!

@mikaelpatel

This comment has been minimized.

Show comment
Hide comment
@mikaelpatel

mikaelpatel Mar 14, 2013

Found some information about what is missing in the Arduino build process:
http://tinkerlog.com/2007/06/16/using-progmem-and-eemem-with-avrs/

The build (avr-objcopy) must include generation of a .eep file for the sketch, ihex .exe .eep, and this must also be uploaded with these parameters. eeprom:w:.eep:i

Otherwise the EEMEM initialization is not part of the upload.

mikaelpatel commented Mar 14, 2013

Found some information about what is missing in the Arduino build process:
http://tinkerlog.com/2007/06/16/using-progmem-and-eemem-with-avrs/

The build (avr-objcopy) must include generation of a .eep file for the sketch, ihex .exe .eep, and this must also be uploaded with these parameters. eeprom:w:.eep:i

Otherwise the EEMEM initialization is not part of the upload.

@mikaelpatel

This comment has been minimized.

Show comment
Hide comment
@mikaelpatel

mikaelpatel Mar 15, 2013

The workaround right now is to use PROGMEM for the initialization values and perform the eeprom initialization in code.

uint8_t is_first_run EEMEM; // will have the value 255
config_t config EEMEM; // configuration value in eeprom
config_t config0 PROGMEM = { ... }; // initial configuration value

if (is_first_run) {
config_t temp;
pgm_read_block(&temp, &config0, sizeof(temp)); // load the configuration initialization
eeprom_write_block(&config, &temp, sizeof(temp)); // store to eeprom
eeprom_write_byte(&is_first_run, 0); // mark as initiated
}

Cheers!

mikaelpatel commented Mar 15, 2013

The workaround right now is to use PROGMEM for the initialization values and perform the eeprom initialization in code.

uint8_t is_first_run EEMEM; // will have the value 255
config_t config EEMEM; // configuration value in eeprom
config_t config0 PROGMEM = { ... }; // initial configuration value

if (is_first_run) {
config_t temp;
pgm_read_block(&temp, &config0, sizeof(temp)); // load the configuration initialization
eeprom_write_block(&config, &temp, sizeof(temp)); // store to eeprom
eeprom_write_byte(&is_first_run, 0); // mark as initiated
}

Cheers!

@ivazqueznet

This comment has been minimized.

Show comment
Hide comment
@ivazqueznet

ivazqueznet Sep 19, 2013

This is 95% complete, all that's required is a four-year-old patch to processing.app.debug.AvrdudeUploader to tell avrdude to actually upload the .eep file.

ivazqueznet commented Sep 19, 2013

This is 95% complete, all that's required is a four-year-old patch to processing.app.debug.AvrdudeUploader to tell avrdude to actually upload the .eep file.

@ivazqueznet

This comment has been minimized.

Show comment
Hide comment
@ivazqueznet

ivazqueznet Sep 20, 2013

It seems that I spoke prematurely. I just disassembled a ELF file from source that uses EEMEM and I don't see a section for the EEPROM data anywhere.

ivazqueznet commented Sep 20, 2013

It seems that I spoke prematurely. I just disassembled a ELF file from source that uses EEMEM and I don't see a section for the EEPROM data anywhere.

@ffissore ffissore added the New label Feb 27, 2014

@Chris--A

This comment has been minimized.

Show comment
Hide comment
@Chris--A

Chris--A Mar 30, 2014

Contributor

I do see one using avr-nm,

00800109 B __bss_end
00800109 B _end
00810000 00000015 D _CompileTimeE
00810015 D __eeprom_end

I do not really think it would output anything into the asm. All eeprom variable usage boils down to constant pointers which would be emitted directly in code.

The memory layout above simply shows how the .eep file is laid out, and that file is simply dumped into the eeprom on upload ( using something other than the IDE ).

Contributor

Chris--A commented Mar 30, 2014

I do see one using avr-nm,

00800109 B __bss_end
00800109 B _end
00810000 00000015 D _CompileTimeE
00810015 D __eeprom_end

I do not really think it would output anything into the asm. All eeprom variable usage boils down to constant pointers which would be emitted directly in code.

The memory layout above simply shows how the .eep file is laid out, and that file is simply dumped into the eeprom on upload ( using something other than the IDE ).

@fulda1

This comment has been minimized.

Show comment
Hide comment
@fulda1

fulda1 May 15, 2016

I will refresh this issue.

It look like, that current process of upload is little changed.
first of all parameter for uploading eep have to be added into: Arduino / hardware / arduino / avr / platform.txt
for example:
add line 100: tools.avrdude.upload.params.eep= "-Ueeprom:w:{build.path}/{build.project_name}.eep:i" add line 105: tools.avrdude.program.params.eep= "-Ueeprom:w:{build.path}/{build.project_name}.eep:i"
and then into
Arduino / arduino-core / src / cc / arduino / packages / uploaders / SerialUploader.java
into lines about 110, 205 and 330 add some check if exist file .eep then prefs.put("program.eep", prefs.get("program.params.eep", ""));

The second part seems to complicated for me. :(

fulda1 commented May 15, 2016

I will refresh this issue.

It look like, that current process of upload is little changed.
first of all parameter for uploading eep have to be added into: Arduino / hardware / arduino / avr / platform.txt
for example:
add line 100: tools.avrdude.upload.params.eep= "-Ueeprom:w:{build.path}/{build.project_name}.eep:i" add line 105: tools.avrdude.program.params.eep= "-Ueeprom:w:{build.path}/{build.project_name}.eep:i"
and then into
Arduino / arduino-core / src / cc / arduino / packages / uploaders / SerialUploader.java
into lines about 110, 205 and 330 add some check if exist file .eep then prefs.put("program.eep", prefs.get("program.params.eep", ""));

The second part seems to complicated for me. :(

@fulda1

This comment has been minimized.

Show comment
Hide comment
@fulda1

fulda1 May 23, 2016

Alternative method for patch is here

fulda1 commented May 23, 2016

Alternative method for patch is here

@Testato

This comment has been minimized.

Show comment
Hide comment
@Testato

Testato commented Aug 25, 2016

+1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment