[Top][All Lists]

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

[avr-gcc-list] Re: Larger than 64K memory sections

From: David Brown
Subject: [avr-gcc-list] Re: Larger than 64K memory sections
Date: Wed, 26 Aug 2009 20:48:23 +0200
User-agent: Thunderbird (Windows/20090605)

David Kelly wrote:
On Wed, Aug 26, 2009 at 03:10:05PM +0200, David Brown wrote:
All in all, I can't see any advantage to the OP in using memory
sections here, and I can see a great many complications if it can be
made to work at all.

I agree that with the avr-gcc toolset that a great many complications
will occur if one tries to map 4MB into the existing 4MB memory space
used by the linker. For lack of multiple address spaces the AVR tools
magically assume an address space way out in never-never land is EEPROM.
Perhaps the linker can be made 64-bit with minimal effort?

A 32-bit address space has 4 GB, so there is no need to go to 64-bit. But the avr-gcc tools already have some "magic" to fit a 16-bit data space, 16-bit eeprom space, and >16-bit flash space at different addresses within a virtual 32-bit address space that does not really exist on the avr. Adding new large address spaces may be easy, or it may be complicated - I have not tried this myself, but I it would at least require some effort to understand the existing system and see what is involved.

I disagree with the claim that mapping external regions like this in to
linker address space is a bad idea. We know nothing of the user's
application or design for utilizing this space. Is very useful to create
named globals and let the linker assign the address whether or not this
global is in FLASH, RAM, EEPROM, or an external device. Otherwise one
must manually manage allocation.

You are right that we know nothing about the application in question - details here would make it much easier to give recommendations. But for most purposes, standard allocation of global data in memory spaces is only suitable for code flash and ram data - not eeprom, external flash, or external devices. The problem is that the compiler and/or linker are free to re-order and re-arrange any objects they allocate.

Suppose you've made a payment card application. In one place, you've got an eeprom-allocated variable "moneyLeft", and in another place you've got "runTimeSeconds". When re-compiling after a change, the compiler/linker could easily swap these two - updating software from version 1.00.01 to 1.00.02 would then trash your eeprom data.

It does not matter what addresses are used for ram variables, nor for the flash code that is updated. But very often it /does/ matter for persistent data, and it is certainly important for pre-defined memory maps such as for external peripherals (there is a good reason why internal peripherals are not defined in a file with lines like "volatile uint8_t PORTD" !). The only way to be entirely sure that an object is allocated to the same address each time is for it to be the only thing in a section, and the section is given an explicit address at link time. When you are talking about data that can't be addressed directly in C on the AVR anyway, why bother with that?

Note that you /can/ (and should) get the compiler to do most of the effort in the allocation. The easiest way is to make a struct type for all your eeprom data:

        typedef struct { uint16_t moneyLeft; uint16_t runTimeSeconds; }

Then you can access this data with something like:

        eeprom_read_word((uint16_t*) (baseAddress +
                        offsetof(eepromData, runTimeSeconds)));

You manually specify a base address, and let the compiler handle the rest.

The same sort of system will work for external data, although I would guess that the 4 MB flash will be filled with an array or other such structure - it would be easier to fit the details within getter and setter access functions. Typedef'ed structs, offsetof and sizeof will probably still feature in the code - precisely to avoid manual allocation.

reply via email to

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