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

[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: Thu, 27 Aug 2009 15:13:21 +0200
User-agent: Thunderbird 2.0.0.22 (Windows/20090605)

Tero Sinervo wrote:
David Brown wrote:
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?

Yes, very often but not always. Consider having text strings in pgmspace but running out of space. Good thing you have a mass storage and file system - you can move the text strings to an external section and load the section to a file. Only thing you need to do is write a driver that replaces pgmspace string stuff with file access. It doesn't matter in which order the strings are in the file.


That's a good example, and in general if the external data is updated with the software, then there is no need to be consistent about the addresses. In that case an external section can do the job.

But you want to be very sure that the external data /is/ consistent - I've worked with systems where the text strings were in an external eeprom, which should have been updated with the software. Since (by mistake) they were not updated, test systems started showing messages in the wrong language...

I often find that when you want to generate data for external memory like this, a C compiler is not the best tool for the job in the first place.


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; }
    eepromData;

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.

This is all all right although perhaps offsetof is redundant:

eepromData* eeprom = BASEADDRESS;
eeprom_read_word(&eeprom->runTimeSeconds);


Yes, that's a neater way to write it in this case. Writing the sums manually (with offsetof) is perhaps easier to adapt to 32-bit addresses for an external 4 MB flash, and also possibly easier to relocate to different base addresses. It all gets buried away in accessor functions or macros, so you should write whatever way you think is clearest.






reply via email to

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