[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [avr-libc-dev] Interrupt vector redirection scheme
From: |
Dmitry K. |
Subject: |
Re: [avr-libc-dev] Interrupt vector redirection scheme |
Date: |
Mon, 3 Sep 2007 08:37:10 +1100 |
User-agent: |
KMail/1.5 |
On Friday 31 August 2007 20:06, Michael Schulze wrote:
> Hi all,
>
> I propose a new interrupt vector redirection scheme which can be
> integrated seamless into the avr-libc in my opinion without having side
> effects.
[...]
Very interesting idea.
Though there is a discrepancy: function redir_func() keeps
the SREG already after it is scratched (sbiw, eor).
Efficiency. I have tried to rewrite this example in classical
style (Redirection on C programming level). As a result the size
of the program has decreased about 682 bytes up to 604 bytes
(arv-gcc 4.1.1).
Regards,
Dmitry.
The "classic" modification:
------------------------------------------------------------
#define F_CPU 16000000
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define DEBUG_INIT() do { \
UBRR0H = (unsigned char) (51>>8); \
UBRR0L = (unsigned char) 51; \
/* Enable UART receiver and transmitter */ \
UCSR0B = ( ( 1 << RXEN0 ) | ( 1 << TXEN0 ) ); \
/* Set frame format: 8N1 */ \
UCSR0C = (1<<UCSZ01)|(1<<UCSZ00); \
} while (0)
#define DEBUG(string) do { \
volatile char* stri = string; \
while( *stri ){ \
/* Wait for empty transmit buffer */ \
while ( !(UCSR0A & (1<<UDRE0)) ); \
/* Start transmittion */ \
UDR0 = (unsigned char) *stri++; \
} } while (0)
// Binding the ISR directly to the interrupt vector
// Timer3 overflow interrupt service routine will and
// can never be changed
ISR(TIMER3_OVF_vect) {
DEBUG("Timer3\n");
}
// Binding a redirection stub to the interrupt vector
// Timer1 overflow interrupt service routine can be
// changed at runtime
volatile unsigned char TIMER1_OVF_vect_REDIR;
ISR(TIMER1_OVF_vect)
{
if (TIMER1_OVF_vect_REDIR == 0)
DEBUG("Timer1\n");
else
DEBUG("Timer1 resurrection\n");
}
int main() {
register uint16_t i = 0x0400;
DEBUG_INIT();
DEBUG("Hallo World\n");
DEBUG("plug in the ISR for timer 1\n");
DEBUG("initialize the the timer 1 and 3\n");
TCCR1B = ((1<<CS12) | (1<<CS10)); // 1024 prescaler = 4s
TIMSK1 = (1<<TOIE1); // enable overflow irq
TCCR3B = ((1<<CS32) | (1<<CS30)); // 1024 prescaler = 4s
TIMSK3 = (1<<TOIE3); // enable overflow irq
DEBUG("allow interrupts globally\n");
sei(); // enable global interrupts
DEBUG("Wait some time before changing the ISR of timer 1\n");
while ( i-- ){
_delay_ms(20);
}
DEBUG("pluging in another ISR for timer 1\n");
TIMER1_OVF_vect_REDIR = 1;
while(1);
}
- Re: [avr-libc-dev] Interrupt vector redirection scheme,
Dmitry K. <=