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

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

Re: [avr-gcc-list] Using Named Address spaces.


From: Erik Christiansen
Subject: Re: [avr-gcc-list] Using Named Address spaces.
Date: Fri, 15 Mar 2013 21:12:59 +1100
User-agent: Mutt/1.5.21+145 (2a1c5d3dd72e) (2012-12-30)

On 13.03.13 22:15, Thomas, George wrote:
> 1. If __flash5 is used then for placing the code we get only 0x50000 
> to the rest of the flash for storing code (.text) . How can we make use 
> of the space before in a case where __flash1 - 4 are absent ?

As in all things *nix, allowing a high level of flexibility can
sometimes seem to allow a user to shoot himself in the foot. In this
case, however, we are only talking about the deliberately omitted
flash[1-4] not being used. The first 128 kb is unaffected by the user
decision not to use flash[1-4], and remains fully available. (See below)

Why might a user deliberately choose to leave flash[1-4] unused? Each
__flashN exists only for page alignment with EIND page selection, so it
is most effective to use the pages in sequence, since all of memory is
then used. If a user chooses to skip lower numbered flashN pages, then
we must respect his explicit decision to reserve them for future use.

It would violate POLA if we tried to engineer some way to thwart the
user's decision, AIUI. Does that, in light of the examples below, make
sense to you?

Here's how I see the above use case:

$ avr-gcc -T avr6.x-new -Wl,-Map,flash.map -o flash.elf -DSTUBS=10
-DP0=0x87ff -DP5=0x10000 -DTEXT=0x20000 -mmcu=atmega2560 flash.sx  #¹

That puts 10 stubs, plus 0x87ff bytes into the lower 128 kb of flash, 
chooses to reserve flash[1-4], by using flash5 instead, and populates
0x20000 bytes which do not need to be below 128 kB.

$ avr-objdump -h flash.elf

flash.elf:     file format elf32-avr

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .data         00000000  00800200  00080062  00038a01  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  1 .lowtext      0000890b  00000000  00000000  00000094  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  2 .flash5       00010000  00050000  00050000  0000899f  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .hightext     00020062  00060000  00060000  0001899f  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  4 .stab         00000768  00000000  00000000  00038a04  2**2
                  CONTENTS, READONLY, DEBUGGING
  5 .stabstr      00000054  00000000  00000000  0003916c  2**0
                  CONTENTS, READONLY, DEBUGGING

We can see that the low 128 kB remains fully accessible, flash[1-4] were
reserved as desired, and the high text butts up to that last used
flashN. All exactly as the user has expressed his wishes.

      ------------------ However ------------------

If the user finds that his flash[1-4] reservation is no longer
needed, then the appropriate flashN page choice allows a fully
compacted memory layout choice:

$ avr-gcc -T avr6.x-new -Wl,-Map,flash.map -o flash.elf -DSTUBS=10
-DP0=0x87ff -DP1=0x10000 -DTEXT=0x20000 -mmcu=atmega2560 flash.sx

$ avr-objdump -h flash.elf

flash.elf:     file format elf32-avr

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .data         00000000  00800200  00040062  00038a01  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  1 .lowtext      0000890b  00000000  00000000  00000094  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  2 .flash1       00010000  00010000  00010000  0000899f  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .hightext     00020062  00020000  00020000  0001899f  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  4 .stab         00000768  00000000  00000000  00038a04  2**2
                  CONTENTS, READONLY, DEBUGGING
  5 .stabstr      00000054  00000000  00000000  0003916c  2**0
                  CONTENTS, READONLY, DEBUGGING

Now .hightext is at the VMA of 0x20000, because the user has removed the
deliberate memory hole.

> 2. If the linker scripts are made generic (Adding in scripttempl/avr.sc), 
> can we control the number of flashN sections in the linker scripts as 
> per the size of flash in the device ?   

Yes. At first I thought that invoking an illegally high flashN, thereby
populating flash which does not exist, would generate an acceptable
linker error. But trying the new linker script with e.g.:

»
MEMORY
{
  text   (rx)   : ORIGIN = 0, LENGTH = 384K
«

and -DP3=0x10000, I get:

/usr/lib/gcc/avr/4.3.4/../../../avr/bin/ld: flash.elf section
`.hightext' will not fit in region `text'
/usr/lib/gcc/avr/4.3.4/../../../avr/bin/ld: region `text' overflowed by
98 bytes

OK, that is not enormously specific, so we probably want to generate one of
our choosing, in the linker script. That shouldn't need device-specific
linker script tweaking either. (But we'll have three parts to the error
message, because the memory region overflow will still be flagged.)

I'll add illegal flashN detection. My (initial) plan is to base it on
the size of flash specified.

The linker script generically provides for all of the envisaged 5
flashN, and so covers all cases, without spurious memory utilisation
penalty. The script automatically snugs .hightext down against the
highest flashN populated by the user, avoiding unplanned memory holes.
So the error message is all we need, then? ...

> Adding my understanding of memx (courtesy : 
> http://gcc.gnu.org/onlinedocs/gcc/Named-Address-Spaces.html#AVR%20Named%20Address%20Spaces)
>  

Thank you, I thought that there wasn't much more than that. :-)

> The __memx qualifier can be use to load and access variables in 24 bit
> address spaces which linearizes flash and RAM. If the high bit of the
> address is set, data is read from RAM using the lower two bytes as RAM
> address. The loading from flash works by making use of the ELPM
> instruction available in AVR.

That describes a run-time read-interface to memory, AIUI. It is another
view of what is more explicitly described in the linker script, in other
terms.

> 
> How it does this ?
...

> The sbrc instruction checks if the location is a program memory or RAM. 
> (checking high bits)

That run-time flip pretty much confirms it. ;-)
AFAICT, __memx is a linear "integrated compiler view" of the AVR's
discrete memory spaces, which does not have any need to manifest itself
in the linker script.

> Also .progmemx.data is the section the data falls into

Hmmm ... a real-world memory model which can use that needs to be
described, I think. My problem is that __memx is a linear memory space
encompassing _all_ of flash and _all_ of RAM. How then is it envisaged
that any data requires a __memx attribute (because all data is already
within all of flash and all of RAM), and how can all of flash and all of
RAM be represented inside one flash input segment, which is less than,
and contained within, _all_???

> (So as per current linker scripts goes in flash) As far as I
> understand __memx is a qualifier that is intended to be used primarily
> as a pointer to access data rather than to store data. (unification of
> RAM and FLASH)  

AIUI, that is all it can be used for. The new linker script has no memx
artifact of any kind, and AFAICT, there is as yet no case for adding
any. (Well, that's today's level of awareness.)

If there's anything I'm missing, please set the record straight.
And if there's anything else we need to add to the linker script ...
well I've been waiting a little while now for an excuse to tweak it some
more.

Thank you for giving it some exercise. The thought you're putting into
corner cases and architecture-variability handling are just what's
needed, I figure.

Erik

¹ For casual readers: flash.sx is Johann's test framework, which he has
  posted (two versions) in one of the two earlier threads on this topic.

-- 
Blessed is he who expects nothing, for he shall never be disappointed.
                                                     - Alexander Pope



reply via email to

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