This topic moved to avr-libc-dev and then to gcc-help, but I forgot to post the conclusion to avr-chat and close off the thread here.
Using the gcc "asm" keyword simplifies defining interrupt methods in C++ classes. The asm keyword as it applies to function names is described in 5.37 of the gcc manual and is mentioned in the asm cookbook section of the avr-libc user manual. It specifies the equivalent assembler name for the target function name and its use allows the user to define his or her own names for class interrupt methods. For avr-gcc it requires the macro: #define CLASS_IRQ(name, vector) \ static void name(void) asm(__STRINGIFY(vector)) \ __attribute__ ((signal, __INTR_ATTRS)) Using the simple example of previous posts on this topic, the interrupt class header for a '128 TIMER0 overflow looks like: class CTimer0Interrupt { public: CTimer0Interrupt(); ~CTimer0Interrupt(); private: CLASS_IRQ(OverflowInterrupt, TIMER0_OVF_vect); }; The macro declares the interrupt handler as static because providing a non-static signal function with a this pointer seems rather hit and miss for gcc. Mandating a static declaration ensures the programmer is not tempted to manipulate any class local data. The cpp implementation file looks like: //*************************************************************** // Timer0Interrupt.cpp // #include "Timer0.h" #include "Timer0Interrupt.h" extern CTimer0 Timer0; //--------------------------------------------------------------- CTimer0Interrupt::CTimer0Interrupt() { TCNT0 = TIMER0_TIMEOUT; TCCR0 = 0x04; TIMSK |= (1<<TOIE0); // enable overflow interrupts } //--------------------------------------------------------------- CTimer0Interrupt::~CTimer0Interrupt() { TIMSK &= ~(1<<TOIE0); // disable Timer0 timeout interrupt } //--------------------------------------------------------------- void CTimer0Interrupt::OverflowInterrupt(void) { TCNT0 = TIMER0_TIMEOUT; // restart the timeout Timer0.SetOverflowFlag(); // tell our friend of the event } Note that the interrupt handler is declared just like any other method. All processing associated with the interrupt is performed in the class associated with, and responsible for, controlling the peripheral. In this case the CTimer0 class of which the CTimer0Interrupt class is both class data and a friend: class CTimer0 { friend class CTimer0Interrupt; public: CTimer0(); ~CTimer0(); int GetTimer0Flags(void); private: void SetOverflowFlag(void); private: volatile int mTimer0Flags; CTimer0Interrupt mTimer0Interrupt; }; Where speed is of the essence, the interrupt class can directly modify the owning peripheral class data. A very simple example is: void CTimer0Interrupt::OverflowInterrupt(void) { TCNT0 = TIMER0_TIMEOUT; // restart the timeout Timer0.mTimer0Flags |= TIMER0_OVERFLOW; } To me this seems a good solution for handling interrupts in avr-gcc C++ projects by integrating the handlers into the peripheral class and keeping with the spirit of C++. Ron E-mail message checked by Spyware Doctor (5.5.0.178) Database version: 5.09110 http://www.pctools.com/spyware-doctor/ _______________________________________________ AVR-chat mailing list AVR-chat@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-chat