[Top][All Lists]
[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))?!
- [avr-gcc-list] Atmega168: __vector_18 interruptible,
Felipe Hernan <=