[Top][All Lists]
[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