avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] Allocation sequence of eeprom variables


From: David Brown
Subject: Re: [avr-gcc-list] Allocation sequence of eeprom variables
Date: Mon, 20 Aug 2012 22:08:17 +0200
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.24) Gecko/20111108 Fedora/3.1.16-1.fc14 Lightning/1.0b3pre Thunderbird/3.1.16

On 20/08/12 19:36, Georg-Johann Lay wrote:
Juergen Harms schrieb:

I am presently switching from a rather obsolete version of avr-gcc
(1.6.1, downloaded as a tarball) to a much newer one (4.6.2, available
in an rpm package on my Mageia distribution),

avr-gcc started around 2011, with GCC version 2.95 or 3.0 or EGCS.

[...] My question here is a problem which I have not solved yet: the
old version of gcc (1.6.1) allocates eeprom variables in the sequence
they appear in the source code to increasing addresses. The new one
does the allocation in the opposite order (within each object-code
module): the first wariable goes to the last address of the module
within the .eeprom section etc.

The order in which the variables are located is not specified.

Since I use eeprom to preserve data between different executions, that
creates serious problems if - between two runs - I reload the
executable code - once generated by my old gcc, once generated by my
new one, eeprom variables being compiled into different locations.

Any advice how to deal with this problem? Thanks!

Don't rely on unspecified behavior. It's a bad design pattern...

The location of data is worked out by binutils (ld), not by the
compiler proper (gcc). Thus, you can:

- Make the location explicit by writing/supplying your own linker
script, cf. [1]. Tedious because every change in the C file needs
an according change in the ld script.

- Layout all eeprom data as a struct. Then it is just *one* object,
not a zoo of objects. You can determine the start address by, say,
-Wl,-section-start=.eeprom=0x810001 if you use gcc as linker driver.

I /strongly/ recommend this option. It is the only one that makes everything clear and explicit, while avoiding counting errors in manual hard-coded addressing. Don't mess around with sections and linker files - even if you are familiar with these, it's too easy to get them wrong. Using linker sections also does not scale - what happens when you want to add some data in one area? With sections, you either end up with multiple sections with very artificial names to get the order right - or you change the structure of your eeprom data. With a struct, you make exactly the changes you want.


- Put each object in its own input section and let the linker sort the
sections per name, see command options or ld script commands. Use
an order that reflects the desired location sequence.

- Use hard-coded addresses like eeprom_read_byte ((const void*) 1);
this is not nice, not recommended and hard to maintain.

Johann


--

[1] http://sourceware.org/binutils/docs-2.22/ld/Input-Section-Example.html




reply via email to

[Prev in Thread] Current Thread [Next in Thread]