avr-gcc doesn't know address space wraps?
Georg-Johann Lay
avr@gjlay.de
Sun Jan 3 20:19:00 GMT 2016
Ralph Doncaster schrieb:
> On Sun, Jan 3, 2016 at 2:36 PM, Georg-Johann Lay <avr@gjlay.de> wrote:
>> Ralph Doncaster schrieb:
>>
>>> On Sun, Jan 3, 2016 at 1:22 PM, Georg-Johann Lay <avr@gjlay.de> wrote:
>>>> Ralph Doncaster schrieb:
>>>>> avr-gcc 4.9.2 doesn't seem to know that the address space wraps, so
>>>>> that an rjmp in the last 2KB of the address space can reach code in
>>>>> the first 2KB.
> [...]
>> Well, you are using RJMP with an address that's out of scope, hence the
>> linker/locator complains. The compiler would not generate code like
>>
>>>>> rjmp ResetVector
> [...]
>> Third approach is to link with --pmem-wrap-around= so that no explicit
>> offset and no explicit RJMP is needed in the code.
>
> Thanks for the reference to the --pmem-wrap-around= option. I
> understand what's going on now; even though the compiler knows the MCU
> (-mmcu=), that does not get passed to the linker. Since the linker
> doesn't know the exact flash size of the part it is linking for, that
> has to be specified with the --pmem-wrap-around option. In this case,
> with a m328p, adding "-Wl,--relax -Wl,--pmem-wrap-around=32k" does the
> trick.
In the old days, the driver tried to deduce the flash size from -mmcu=
by means of a specs trick. Up to 4.9, avr.h reads:
#define LINK_SPEC "\
%{mrelax:--relax\
%{mpmem-wrap-around:%{mmcu=at90usb8*:--pmem-wrap-around=8k}\
%{mmcu=atmega16*:--pmem-wrap-around=16k}\
%{mmcu=atmega32*|\
mmcu=at90can32*:--pmem-wrap-around=32k}\
%{mmcu=atmega64*|\
mmcu=at90can64*|\
mmcu=at90usb64*:--pmem-wrap-around=64k}}}\
..."
I ported this to the GCC 5 spec file approach of device support so that
it should work in v5. However the device names are much to diverse, and
such an approach is not very sensible today (-mpmen-wrap-around isn't
even documented). A proper approach would add flash sizes to
avr-mcus.def, and whereby eventually to device-specs. The device-specs
for your device, specs-atmega328p, reads
*link_pmem_wrap:
%{mpmem-wrap-around: --pmem-wrap-around=32k}
*link_relax:
%{mrelax:--relax %(link_pmem_wrap)}
so that it's a bit more convenient to let addresses wrap (link_relax is
part of LINK_SPEC). -mpmem-wrap-around is supposed to work with 4.9,
but it does not for some reasons.
More information about the Gcc
mailing list