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

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

RE: [avr-gcc-list] Re: eicall & EIND


From: Dusan Ferbas
Subject: RE: [avr-gcc-list] Re: eicall & EIND
Date: Wed, 11 Mar 2009 23:57:31 +0100

At 16:10 11.3.2009, you wrote:
> We are using Nut/OS, where you can setup interrupt handler
> address at run time.

Interesting.  Is this done through a single "master interrupt"?  You
cannot rewrite the vector table real-time.  Just curious.

1)
I like your laughing approach. But finally "I think you've got it".
Bootloader is 2kB long, because we digged almost every flash space from ATmega128.
It is not bad for an http upgradability with an encryption.
Of course we set boot fuse, we do not use ints in BL.
We compile both separately and use a jump table at the beginning of the BL
If you look here http://lists.gnu.org/archive/html/avr-gcc-list/2008-06/msg00031.html,
we emailed last year.
No chance to use jump table from a not yet present application.

2) BL is called iteratively as packets are coming in from a TCP connection
eicall in bootloader (no rcall) - is caused by:
fn[sect_id](address, buf, len); //fn is an array of fn pointers
switch/case construction is not flexible and consumes more space

3) Nut/OS
You can look at sourceforge.net/projects/ethernut/. FYC here are snippets.

Regarding your "master interrupt" - a lesson here:
When using a fn pointer in CallHandler, this generates eicall.

typedef struct {
    u_long ir_count;
    void *ir_arg;
    void (*ir_handler) (void *);
} IRQ_HANDLER;

#define NUTSIGNAL(signame,handler)      \
SIGNAL(signame)         \
{ CallHandler (&handler);  }

IRQ_HANDLER sig_INTERRUPT5;

...
NUTSIGNAL(SIG_INTERRUPT5, sig_INTERRUPT5)
...

void CallHandler(IRQ_HANDLER * irh)
{
    irh->ir_count++;
    if (irh->ir_handler)
        (irh->ir_handler) (irh->ir_arg);                        //-> eicall
}


> Now, I have a bootloader. Simple, no interrupts, part of it
> is called from an application to allow http upgrade.
> There is a decryption and then data based selection of
> routines to burn into different places - flash/eeprom/SPI flash.
> For this eicall seems to be proper way. But eind is expected
> to be 1 now, axiom #1. We manually has to force this and then
> reload 0 back.

The common solution to the "interrupts when running in the BLS" problem
is to generate the boot as a totally separate application, then use the
IVSEL control bit to set the processor to use the vector table at the
beginning of the BLS.

I was one of the "weird" guys who didn't follow this approach.  There
are both good things and bad things to not writing the boot as an
application, and the one bad is that interrupts are pretty much thrown
out the window.

EIND should not be needed by general code in the bootloader.  The
compiler rarely uses the EICALL/EIJMP instruction but instead tends to
use RJMP/RCALL.  The only place I know that it is used is when the
single call prologue is used (the compiler switch -mno-call-prologues
turns this off).  The mega2560 library should *not* be using that in the
latest RC version of WinAVR, and that may have been fixed in WinAVR
20081205.

If you are upgrading the application, don't you want to restart the O/S
as well?  The usual method to do that is to force a watchdog timeout,
which will cause a CPU reset and clear all interrupt flags (which is
what you want anyway) and all the control registers, EIND included.

Dusan




reply via email to

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