avr-libc-dev
[Top][All Lists]
Advanced

[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);
}





reply via email to

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