[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: [avr-gcc-list] ATmega 2561 - compiler generates eicall
From: |
Stu Bell |
Subject: |
RE: [avr-gcc-list] ATmega 2561 - compiler generates eicall |
Date: |
Wed, 4 Jun 2008 08:24:40 -0600 |
By the addresses it appears that you are using an ATmega2560 or 2561.
You are trying to use function pointers for upper flash (beyond the 128
Kbyte/64 Kword boundary).
The current GCC compiler does not know how to do this. Function
pointers are kept as 2 byte entities. While static (non-pointer)
function calls are dealt with using a neat device called a "trampoline"
(essentially a table of eijmps that the local function can call),
function pointers do not use this device.
I have the same problem and have resolved it by assigning all of my
pointer targets *and callers* into a separate linker section that is
forced into the lower part of flash. I have the following macro:
#define COMMAND_HANDLER __attribute__ ((section (".fptr_target")))
Which I append to each function target prototype, for example:
CmdError CmdInitTrack( CmdPacket* pCmdPkt ) COMMAND_HANDLER;
Then, I created a custom linker script from avr6.x to place this section
in low flash:
. . .
/* Internal text space or external memory. */
.text :
{
. . .
KEEP (*(.init8))
*(.init9) /* Call main(). */
KEEP (*(.init9))
/* Interrupt Service Routine code needs to be in the lower 128K
program */
*(.isr)
KEEP(*(.isr))
/* Any code that is the target of a function pointer must also
reside in lower memory */
*(.fptr_target)
KEEP(*(.fptr_target))
/* An RTOS task should also be in low mmeory. */
*(.task)
KEEP(*(.task))
/* Main code starts here - this code can oveflow into the upper 128K
program */
*(.text)
. = ALIGN(2);
*(.text.*)
. = ALIGN(2);
*(.fini9) /* _exit() starts here. */
. . .
As you may notice, there are also two other custom sections, .isr and
.task. All ISRs go into the .isr section for the same reason as the
function pointer targets -- the vector table will default jump only to
the low part of flash. I accomplished this by having the following
macro:
#define ISR_SECTION __attribute__ ((section (".isr")))
And making all of my ISR declarations...
ISR( TIMER_OVERFLOW_SIG, ISR_BLOCK ISR_SECTION )
(Note the lack of a comma between ISR_BLOCK and ISR_SECTION -- not sure
why that must be, but it did not compile if a comma was there.)
The .task section is for RTOS task functions. Since the tasks are
created at run time by pssing a function pointer to the task creation
mechanism, they fall under the same rules as the function pointers.
Using these techniques I have been able to get my code running under
WinAVR 20080521. Hopefully, you can to.
Best of luck!
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