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

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

RE: [avr-gcc-list] custom signal prologue


From: Ben Mann
Subject: RE: [avr-gcc-list] custom signal prologue
Date: Wed, 24 Nov 2004 08:37:57 +0800

I had attempted the same thing but also wasn't wild about
reverse-engineering the register list after any changes.

I quite like Christian's solution to this problem, which allows a much
cleaner approach to managing the registers, albeit at the cost of an extra
function call (ie call/ret overhead). For the time being I'm using this
method.

Now, if there were a way to make my function call inline, and thereby
magically instantiate the prologue without the call/ret pair, ie like this:

inline void MyInterruptHandler(void) __attribute__ ((signal,always_inline));
inline void MyInterruptHandler(void) {
    ...Do Something...
}

void SIG_UART1_DATA(void) __attribute__ ((naked));
void SIG_UART1_DATA(void) //SIGNAL(SIG_UART1_DATA)
{   
    //Disable UDRIE
    BYTE UCSRBReg;
    asm volatile ("push %0\n\t" : "=r" (UCSRBReg) :);
    UCSRBReg= UCSR1B;
    UCSR1B = UCSRBReg& ~_BV(UDRIE);
    //Enable interrupts
    sei();
    asm volatile ("pop %0\n\t" : "=r" (UCSRBReg) :);
    //Do our work
    MyInterruptHandler();
    //Bye
    asm volatile("ret\n\t" : :);
}

Then I think it would be a fantastic solution. Of course, it doesn't work as
is, apparently as the compiler doesn't want to inline something with
prologue/epilogue etc....

Ben Mann



-----Original Message-----
From: address@hidden [mailto:address@hidden
On Behalf Of Jim Brain
Sent: Tuesday, 23 November 2004 10:56 PM
To: AVR GCC List
Subject: Re: [avr-gcc-list] custom signal prologue


Ben Mann wrote:

>Hi all,
>
>Is there any way to customise the prologue of an interrupt handler?
>  
>
I had the same issue.  I'm interested in responses you receive, but here is
what I did:

#ifdef JOY_ASM_INT
void SIG_OUTPUT_COMPARE1A (void) __attribute__ ((interrupt))
__attribute__ ((naked));    \
void SIG_OUTPUT_COMPARE1A (void) {
asm volatile ("push r24" ::);
asm volatile ("push __tmp_reg__" ::);
#else
INTERRUPT(SIG_OUTPUT_COMPARE1A) {
#endif
  // bring output high
  JOY_POT_PORT|=(1<<JOY_POT_PIN_X);
  // turn off IRQ
  TIMSK&=(unsigned char)~(1<<OCIE1A);
   sei();
  if((TIFR & (1<<OCF1B)) != 0) {
    JOY_POT_PORT|=(1<<JOY_POT_PIN_Y);
  }
#ifdef JOY_ASM_INT
asm volatile ("pop __tmp_reg__" ::);
asm volatile ("pop r24" ::);
asm volatile ("reti" ::);
#endif
}

I compile with JOY_ASM_INT undefined, and see what registers the routine
requires.  I then tweak the ASM and recompile with JOY_ASM_INT defined.

I'm not wild about my solution, but I absolutely had to remove all the
extraneous pushes and pops, or the code was worthless.

Jim



-- 
Jim Brain, Brain Innovations
address@hidden                                http://www.jbrain.com
Dabbling in WWW, Embedded Systems, Old CBM computers, and Good Times!



_______________________________________________
avr-gcc-list mailing list
address@hidden http://www.avr1.org/mailman/listinfo/avr-gcc-list





reply via email to

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