[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [avr-gcc-list] ATmega 2561 - eicall uses "byte" address
From: |
hutchinsonandy |
Subject: |
Re: [avr-gcc-list] ATmega 2561 - eicall uses "byte" address |
Date: |
Fri, 06 Jun 2008 07:47:39 -0400 |
Compiler should not need "near". This is a constant address. So it
should do CALL, which can be handle like any other call.
This is a bug.
Andy
----------------------------------------------
Sent from my Dingleberry wired device.
-----Original Message-----
From: Dusan Ferbas <address@hidden>
To: Stu Bell <address@hidden>; address@hidden
Sent: Thu, 5 Jun 2008 7:29 pm
Subject: RE: [avr-gcc-list] ATmega 2561 - eicall uses "byte" address
Hi Stu,
as you said - why not to read the whole email :-).
In bootloader code we can live with EIND=1 at its init.
I now checked the case also with WinAVR-20080512. Same bug as with
20071221 (WinAVR bug #1959227 at sf.net).
Is it possible to add an attribute st. like "near" to prevent compiler
using eicall and to generate icall (case 1 below) ?
--------------
case 1 (bootloader)
Problem is not with indirect call through a pointer saved in RAM.
typedef void (* WriteFN)(unsigned short page, unsigned short *data,
unsigned short len);
...
WriteFN fn[3];
...
fn[0] = FlashPage; //FlashPage/2 (word address) is used
...
fn[0](page, data, len);
-> eicall generated by compiler, which does not know, that the code
will be positioned with linker to an address in upper flash
(EIND=1 solves this)
Here I would like to have an icall instruction.
--------------
case 2 (application calling fn in bootloader)
Problem is with "direct" call generated with eicall aid. I understand,
that compiler cannot count with link addresses,
but when address is constant even during compilation time, then it is
definitely a compiler bug.
typedef void Tboot_loader_data_init(unsigned char *);
#define boot_loader_data_init ((Tboot_loader_data_init *)0x3F806)
boot_loader_data_init(buffer)
typedef void Tboot_loader_data_init(unsigned char *);
#define boot_loader_data_init ((Tboot_loader_data_init *)(0x3F806/2))
...
EIND = 0x3F800 >> 17;
boot_loader_data_init(workbuf);
EIND = 0x00;
avr-gcc (GCC) 4.2.2 (WinAVR 20071221), ATmega2561
241 0068 81E0 ldi r24,lo8(1)
242 006a 8CBF out 92-0x20,r24
243 006c C501 movw r24,r10
244 006e E3E0 ldi r30,lo8(-1021)
245 0070 FCEF ldi r31,hi8(-1021)
246 0072 1995 eicall
Here you can see, that a workaround was needed. To have a word address,
avr-gcc (GCC) 4.2.2 (WinAVR 20071221), ATmega128
#define boot_loader_data_init ((Tboot_loader_data_init *)0x1F806)
229 0054 E6E0 ldi r30,lo8(-2042)
230 0056 F8EF ldi r31,hi8(-2042)
231 0058 0995 icall
Also for ATmega128, no division is done by gcc 4.2.2
avr-gcc (GCC) 3.4.6, ATmega128
#define boot_loader_data_init ((Tboot_loader_data_init *)0x1F806)
741 006c FF95 03FC call -2042
Older gcc uses efficient std call to a word address.
Dusan
=====================
At 16:30 4.6.2008, Stu Bell wrote:
Dang, it would help if I read the entire message.
Function pointers in the bootloader. I kept my bootloader
mind-bogglingly simple precisely to avoid problems like this.
Unfortunately, many folks have a need for a far more comples
bootloader
than I need.
Since the eicall is being used, why not force EIND to 1 at the
beginning
of your code...
asm volatile ( "ldi r24, 0x01 \n\t"
"out 0x3C, r24 \n\t"
);
Worth a shot, eh?
Best regards,
Stu Bell
DataPlay (DPHI, Inc.)
-----Original Message-----
From: address@hidden
[mailto:address@hidden On Behalf
Of
Dusan Ferbas
Sent: Tuesday, June 03, 2008 5:36 PM
To: address@hidden
Subject: [avr-gcc-list] ATmega 2561 - compiler generates eicall
Hi,
I am using WinAVR-20071221, because none of the most recent toolchains
produces a runnable code for our application.
Our bootloader starts at 0x3f800 (2kB).
In its code, we are using function[id](...) construction.
This is compiled with eicall instruction, but no EIND register is set.
Is there a way, how to tell the compiler, that code is linked in upper
half of flash ?
In bootloader code we can live with EIND=1 at its init.
But when we have a call from our application, neither EIND is set,
even
address is not divided by 2 (WinAVR bug #1959227).
Probably some far attribute should be applied ?
When compiled for ATmega128 (with 0x1f806), it works ...
typedef void boot_loader_init(unsigned char *);
#define boot_loader_data_init ((boot_loader_init *)0x3F806)
...
boot_loader_data_init(buffer);
...
Dusan
_______________________________________________
AVR-GCC-list mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Message not available