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

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

RE: [avr-gcc-list] use of specifin RAM location


From: Schwichtenberg, Knut
Subject: RE: [avr-gcc-list] use of specifin RAM location
Date: Wed, 30 Nov 2005 08:21:08 +0100

Hi,

I'm also struggeling with this issue. 

> What's the point of using the abstraction of the C language, 
> then?  The compiler should handle those details for you.
Yes, but sometimes I'm more keen than the compiler. For me I want to
place variable to special location to make access faster. To avoid to
any additional clock cycle I want to place some special variables to
addresses like 0x100. If addresses have a low byte zero and the access
is like tab[indx] are smaller than 0x50 I only need to  put indx*2 into
the low byte of the index register and do not have to make a 16Bit add. 

The first idea is to handle variable in a separate segment in C: But
onlyone variable per segment can be done by this if you need the very
special address. If you put more variables into one segment the sequence
of placement is done by the compiler on his own idea. If you put the
variables into a structure you can not access them from assembler easily
(see at the end).

To make things more complex I'm using a Mega162 with 32kByte of ext.
memory.

I'm using WinAvr_20050214 and binutils 2.16

For testing I have simplified my problem as shown in the attached
archive.

Results:
1. Stackpointer is set in main and therefore the changes in .init2 are
overwritten.
Is this a bug, a known bug or a feature?

2. -minit-stack=nnnn is not working see below
$ make clean;make
rm -f main.hex main.eep main.cof main.elf \
main.map main.sym main.lss \
main.o text.o text.lst main.lst main.d
avr-gcc -c -mmcu=atmega162 -I. -gstabs   -Os -Wall -Wstrict-prototypes
-std=gnu99 -Wa,-adhlns=main.lst main.c -o main.o
avr-gcc -c -mmcu=atmega162 -I. -x assembler-with-cpp
-Wa,-adhlns=text.lst,-gstabs text.S -o text.o
avr-gcc -mmcu=atmega162 -I. -gstabs   -Os -Wall -Wstrict-prototypes
-std=gnu99 -Wa,-adhlns=main.o main.o text.o --output main.elf -Wl,
--section-start=.absolute=0x800200,-minit-stack=0x0400,--section-start=.
data=0x800400,--section-start=.bss=0x800400,--defsym=__heap_en
d=0x80ffff -Wl,-Map=main.map,--cref
c:\WinAVR\bin\..\lib\gcc\avr\3.4.3\..\..\..\..\avr\bin\ld.exe:
unrecognised emulation mode: init-stack=0x0400
Supported emulations: avr2 avr1 avr3 avr4 avr5
make: *** [main.elf] Error 1

3. The segment start addresses are not set as defined
To compile the test sample proper I did the following make:
$ make clean;make
rm -f main.hex main.eep main.cof main.elf \
main.map main.sym main.lss \
main.o text.o text.lst main.lst main.d
avr-gcc -c -mmcu=atmega162 -I. -gstabs   -Os -Wall -Wstrict-prototypes
-std=gnu99 -Wa,-adhlns=main.lst main.c -o main.o
avr-gcc -c -mmcu=atmega162 -I. -x assembler-with-cpp
-Wa,-adhlns=text.lst,-gstabs text.S -o text.o
avr-gcc -mmcu=atmega162 -I. -gstabs   -Os -Wall -Wstrict-prototypes
-std=gnu99 -Wa,-adhlns=main.o main.o text.o --output main.elf -Wl,
--section-start=.absolute=0x800200,--defsym=__stack=0x0400,--section-sta
rt=.data=0x800400,--section-start=.bss=0x800400,--defsym=__hea
p_end=0x80ffff -Wl,-Map=main.map,--cref
avr-objcopy -O ihex -R .eeprom main.elf main.hex
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 -O ihex main.elf main.eep
avr-objcopy --debugging --change-section-address .data-0x800000
--change-section-address .absolute-0x800000 --change-section-address .
bss-0x800000 --change-section-address .noinit-0x800000
--change-section-address .eeprom-0x810000 -O coff-ext-avr main.elf
main.cof

I would expect to see variables being members of the .absolute segment
in the address range >= 0x200 but the are set as below:

.absolute       0x00800200        0x0

absolute        0x000000e2      0x150
 absolute       0x000000e2      0x150 text.o
                0x000000e2                v1
                0x000001e2                v2
                0x00000132                otto

The address 0xe2 is in the middle of the extended registers, so at least
0x100 and bigger are valid RAM addresses. To validate the map file I've
disassebled the ELF-file and added some comments - see attachment.

Any suggestions?



At least if you allocate variables in assembler to place them into
special addresses you need any mechanism to get the right size.
If you write in C:

struct {
   .....
} t_vari;

and define a variable as

extern t_vari vari;

What is the size to define it in assembler? The "sizeof(t_vari)" will
not work, because sizeof is handled by the comiler and not by the cpp.
Any solutions are welcome.

Cheers

Knut

Attachment: absoulte.zip
Description: absoulte.zip


reply via email to

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