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: Bernard Fouche
Subject: RE: [avr-gcc-list] custom signal prologue
Date: Wed, 24 Nov 2004 11:42:29 +0100

If ...do something... is an inline function, you won't loose time
pushing/poping unneeded registers.

Now I wonder if, when just doing sei(), you're are not re-regenerating the
same interrupt. UDRE is cleared after processing the corresponding interrupt
handler or setting UDR. Did you try to set UDR asap in the interrupt handler
and then doing sei() ? That would allow your other time critical interrupt
to be processed. That would be:

SIGNAL(SIG_UART_DATA)
{
        UDR=..getting new data to send... or disabling UDRIE if nothing else to
send;
        sei();
}

Now the purpose of such a signal handler being to send new data if needed,
all the job is already done before sei()!

other solution: did you check using TXCIE instead of UDRIE ? It is written
in the datasheet that you can clear manually the TXC flag when you want. So
you clear it as you enter the signal handler and use sei(). This way another
interrupt can come and be processed really quickly and you won't regenerate
the same interrupt.

 Bernard

-----Message d'origine-----
De : address@hidden
[mailto:address@hidden la part de Ben Mann
Envoye : mardi 23 novembre 2004 13:20
A : address@hidden
Objet : [avr-gcc-list] custom signal prologue


Hi all,

Is there any way to customise the prologue of an interrupt handler?

To explain...

I have a UDR interrupt handler in which I'd like to enable interrupts so
that another very time-critical interrupt can be handled promptly.

The usually accepted method does not work for UDR

 INTERRUPT(SIG_UART_DATA) {
     ...do something...
 }

because as soon as sei is enabled another UDR interrupt immediately triggers
and hangs the processor.

An inefficient but workable solution in C appears to be:

SIGNAL(SIG_UART_DATA) {
    //Disable UDRIE
    UCSRB &= _BV(UDRIE);
    sei();
    ...do something...
    UCSRB |= _BV(UDRIE);
}

The problem being that with complex replacements for "do something", the
prologue consists of pushing qutie a few registers. The trimmed .lst excerpt
below demonstrates the code the compiler generates for the first couple of
lines above in my application.

*********************
push __zero_reg__                               //UDRIE vector
push __tmp_reg__
in __tmp_reg__,__SREG__
push __tmp_reg__
clr __zero_reg__
push r18
push r19
push r20
push r21
push r22
push r23
push r24
push r25
push r26
push r27
push r30
push r31
/* prologue end (size=17) */
lds r24,154  /* disable UDRIE */
andi r24,lo8(-33)
sts 154,r24
sei   /* enable interrupts */
*********************

Is it possible to customise the prologue and somehow do the UDRIE disable
first, ie:

*********************
lds r24,154  /* disable UDRIE */        //UDRIE vector
andi r24,lo8(-33)
sts 154,r24
sei   /* enable interrupts */
push __zero_reg__
push __tmp_reg__
in __tmp_reg__,__SREG__
push __tmp_reg__
clr __zero_reg__
push r18
push r19
push r20
push r21
push r22
push r23
push r24
push r25
push r26
push r27
push r30
push r31
/* prologue end (size=21) */
*********************

For completeness I also looked at the promising and simple idea of:
SIGNAL(SIG_UART_DATA)
{
    //Disable UDRIE
    UCSRB &= _BV(UDRIE);
    sei();
    MyInterruptHandler();
}

Which I thought should require no prologue (MyInterruptHandler() pushing
what it needs) but the compiler still generates a similar looking prologue
for the interrupt handler - even with the interrupt and MyInterruptHandler()
in separate source files... (Which I found a little surprising)

Am I missing something obvious? Has anyone attempted to deal with this
before? (... sorry for the long post...I can't seem to keep it brief...)

Thanks

Ben Mann



_______________________________________________
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]