[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.


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) 
typedef void Tboot_loader_data_init(unsigned char *); 
#define boot_loader_data_init ((Tboot_loader_data_init *)(0x3F806/2)) 
  EIND = 0x3F800 >> 17; 
  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. 
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
than I need. 
Since the eicall is being used, why not force EIND to 1 at the
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
Dusan Ferbas 
Sent: Tuesday, June 03, 2008 5:36 PM 
To: address@hidden
Subject: [avr-gcc-list] ATmega 2561 - compiler generates eicall 
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,
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) 
AVR-GCC-list mailing list 

reply via email to

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