AVR-gnuC interrupt handler question

Sep 04, 2006 7 Replies

Hello, I'm definitely not a C programmer so the answer is probably obvious, but anyway here is my question:



I've a small 4x2 keyboard that's handled through interrupts. Each of the 2 columns is connected to an IT input (resp. INT0 & INT1) I want to serve both interrupts through the same handler.



I'm using WinAVR and AVR-libc, so I have something like the following snippet:



#include



ISR(INT0_vect) { ... }


But I don't understand how to force the compiler to make the INT1 vector point to the INT0 service routine.


Thanks, Fred.

[...]

There's a bad way to do it, and several worse ways to do it. No elegant method exists, really.

What I would suggest is to put a label inside the INT0 ISR and put a goto inside the INT1 ISR. Yuck, yuck, yuck.

But check the disassembly. You MIGHT need to inline an assembly jump to that goto.

Thanks. I thought about this and also going the include way, which avoids duplicating the source code, but not the obj code. I expected there was a cleaner way.

What about the worse ones ?-)

Thanks, Fred.

Isn't it as simple as the following? Not quite the same, but achieves the same result.

ISR(INT0_vect) { Common_Code(); }

ISR(INT1_vect) { Common_Code(); }

void Common_Code() { ... }

~Dave~

Sure that'll work, but I'd like to avoid the huge additional push-pop overhead implied by the function call.

It seems (avrfreaks) there's a solution through using aliasing either through an alias attribute to one of the interrupt routines (clean but not supported in the current winavr built) or through explicitly aliasing at the linking step.

Thanks, Fred.

You could use something like this:

ISR(INT1_vect) __attribute__ ((alias("__vector_1")));

ISR(INT0_vect) { ... }

The string "__vector_1" depends on the vector number of the INT0 interrupt. This is target dependent. I don't know how to avoid putting that literal name in the string.

Regards, Arlet

Unfortunately the alias attribute isn't supported in the current gcc version for winavr (gcc 3.4.6).

Suggested on the avrfreaks forum is to alias the names at the link step (add -Wl,--defsym=__vector_2=__vector_1 ).

Not ultra clean, but works nicely and is said to be supported on the next release, so I'll go for it.

Thanks to all.

Thanks, Fred.

If you structure your code carefully (i.e., make Common_Code() static inline, and defined before the interrupt routines), then there will be no extra push-pop overhead. You'll get the code generated twice, but unless you are using the tiniest of devices (or a huge "Common_Code"), there is no practical problem.

Both these will work. You could also make the second interrupt routine a pure assembly function which jumps directly to the first routine.

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required