On 30.01.2008, at 06:44, Ron Kreymborg wrote:
The interrupt class does not need a this pointer as it neither calls
other
methods in its class or accesses any private class data, so the
interrupt
method itself can correctly be non-static.
Well, "correctly" is a bit strong here. In fact, the behaviour is
undefined and it is just a case of luck (read: compiler-specifica)
that it works. Whereas depending on compiler-specifica is acceptable
for programming on this level, it is just not necessary in your case.
By "correctly" I meant it works fine this way, not that it was the
only way.
Not sure what you mean about undefined. What is undefined?
So why do you not just make it a class function (static) instead of a
member function? They can be private as well, friends as well, their
calling semantics is defined, and the *compiler* would make sure that
you do not (accidentally) access any member elements. No
disadvantages, but more safety.
Good point. My interrupt classes never have local data, so the
possibility
never came up. But for more general use I agree, "static" is the
safer way
to go.
Undefined means that this situation is not specified by the standard.
The compiler is free to assume that this points to a valid instance
and to do what it wants with it. So if you ever switch to another
compiler or the gcc folks decide for whatever reason to do something
fancy in methods, you are lost. This is not very likely, but
nevertheless an avoidable risk. For principle reasons such risks
should be avoided.
Moreover, class functions can be given "C" linkage. Andrew is right
Yes, this is almost working. In the avr-gcc case, a plethora of
processors
have much the same peripherals and the compiler managers have rightly
standardized on common names for common peripherals, with the
translation to
the correct vector done via processor specific macros. My last
problem looks
like it should be easy but I have run out of ideas. It is in the
method
declaration. For example:
static void MyOverflowInterrupt(void) asm(TIMER0_OVF_vect)
__attribute__ ((signal, __INTR_ATTRS));
Somewhere in the device header for a particular processor is the line:
#define TIMER0_OVF_vect _VECTOR(16)
And elsewhere is defined:
#define _VECTOR(N) __vector_ ## N
So the definition becomes the almost correct:
static void MyOverflowInterrupt(void) asm(__vector_16)
__attribute__ ((signal, __INTR_ATTRS));
How do I get it to be:
static void MyOverflowInterrupt(void) asm("__vector_16")
__attribute__ ((signal, __INTR_ATTRS));
Oh, this one is actually easy :-)
You just need another macro-indirection that uses the "stringify"
operator (#) of the pre-processor:
>>>>
lohmann@mocca:~/tmp$ cat test.cpp
#define TIMER0_OVF_vect _VECTOR(16)
#define _VECTOR(N) __vector_ ## N
#define IRQ_VECTOR(vec) asm(#vec) __attribute__ ((signal, __INTR_ATTRS))
class Timer0 {
static void MyOverflowInterrupt(void) IRQ_VECTOR(TIMER0_OVF_vect);
};
<<<<
After pre-processing this becomes:
>>>>
lohmann@mocca:~/tmp$ g++ -E test.cpp
class Timer0 {
static void MyOverflowInterrupt(void) asm("TIMER0_OVF_vect")
__attribute__ ((signal, __INTR_ATTRS));
};
<<<<
Daniel
P.S. Answers to to the list, please. Other readers might be
interested and contribute as well.