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

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

[avr-gcc-list] Atmega168: __vector_18 interruptible


From: Felipe Hernan
Subject: [avr-gcc-list] Atmega168: __vector_18 interruptible
Date: Wed, 26 Sep 2007 16:34:08 -0400

   __attribute__((interrupt)) allows to a vector to be interrupted
re-enabling the global interrupt flag.
 ┬┐Why I need this?

 During __vector_18 (SIG_USART_RECV | USAR_RX_vect in libc) execution
I need TIMER0_OVF_vect interruption.

 The reason

 My program implement a communication protocol for microcontrollers
over RS232/485. The implementation should
discard any frame (frame is in bytes) malformed or incomplete.
Actually the way to detect incomplete frame is reading the last byte's
timestamp and compare it against current, if that delta is
greater than RX_TIMEOUT, then bytes isn't continuous, if delta isn't
greater and frame is complete, an user callback is called.
Additionally the protocol support an send option of  Acknowledge that
needly use TIMER0 and maybe a _send_
is called from a user callback.

  Here a possible call stack

__vector_18->rx_protocol->user_callback->send_frame

Where send_frame has Acknowledge option.

The project goal is a subsystem based in events, We dont want to add
poll functions on main thead nor to add additional loop.

The problem

interrupt attribute not WORKS!. When a RX interrupt is done, the program dead.

 I use "naked" attribute in __vector_18 and I add a __asm__("sei" ::)
as prologue,  __asm__("reti ::") as epilogue and WORKS!

#if defined(__AVR_ATmega168__)
void USART_RX_vect(void) __attribute__((naked));
void USART_RX_vect(void)
#else
void USART_RXC_vect(void) __attribute__((naked));
void USART_RXC_vect(void)
#endif
{
        sei();
#if defined(__AVR_ATmega168__)
        unsigned char c = UDR0;
#else
        unsigned char c = UDR;
#endif
        hal_rx_cb(c);
        asm("reti" ::);
}

output with -O3:

00000078 <__vector_18>:
  78:   78 94           sei
  7a:   80 91 c6 00     lds     r24, 0x00C6
  7e:   e0 91 00 00     lds     r30, 0x0000
  82:   f0 91 00 00     lds     r31, 0x0000
  86:   09 95           icall
  88:   18 95           reti

Why happens with __attribute__((interrupt))?!




reply via email to

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