Доброго времени суток! Позвольте вклиниться в разговор...
Цитата(ReAl @ Aug 3 2009, 18:47)

А что толку? Всё равно ничего не получится. Там разговор шёл про патч - атрибуту signal дать как аргумент номер прерывания и позволить произвольные имена, но, насколько я понял, до "официальных" версий это так и не дошло.
Так что
приходится так, как уже писалось - с "друзьями" (OS_INTERRUPT из avr-gcc порта scmRTOS) ...
Вчера назрел подобный вопрос, пришлось заняться "разборками". Как выяснилось, вопрос вполне решабельный, и после оперативно-разыскных мероприятий по всему инету есть что сказать. Начну по порядку.
1.
C++ InterruptsЦитата
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.
2.
Controlling Names Used in Assembler CodeЦитата
You cannot use asm in this way in a function definition; but you can get the same effect by writing a declaration for the function before its definition and putting asm there, like this:
Код
extern func () asm ("FUNC");
func (x, y)
int x, y;
...
Изначальный макрос у меня "с пол пинка" не завелся, но после некоторого экспериментирования, пришел к такому коду:
Код
// Timer.h
#include <avr/interrupt.h>
#define OS_INTERRUPT extern "C" __attribute__((__signal__,__INTR_ATTRS))
class Timer
{
public:
Timer( ) { }
~Timer( ) { }
void Dispatch( ) { }
static void IRQHandler( ) asm( "__vector_10" ); // Или, не 10 ( взято "с потолка" ), в любом случае, меняя нумер можно
// подставить куда угодно
};
Код
// Timer.cpp
#include "Timer.h"
Timer timer;
//---------------------------------------------------------------
OS_INTERRUPT void Timer::IRQHandler(void)
{
timer.Dispatch( );
}
Проверяем, что получилось...
Код
$ nm Timer.o
00000150 t _GLOBAL__D_timer
00000138 t _GLOBAL__I_timer
000000d4 t _Z41__static_initialization_and_destruction_0ii
00000054 W _ZN5Timer8DispatchEv
00000000 W _ZN5TimerC1Ev
0000002a W _ZN5TimerD1Ev
0000003e a __SP_H__
0000003d a __SP_L__
0000003f a __SREG__
U __do_clear_bss
U __do_copy_data
U __do_global_ctors
U __do_global_dtors
00000000 a __tmp_reg__
0000007e T __vector_10 <===== Оно!
00000001 a __zero_reg__
00000000 B timer
Аха-а-а! Наш вектор экспортируется под "правильным" именем!
Теперь глянем на дизассемблированный листинг:
Код
Disassembly of section .text:
00000000 <__vectors>:
0: 1b c0 rjmp .+54 ; 0x38 <__dtors_end>
2: 3f c0 rjmp .+126 ; 0x82 <__bad_interrupt>
4: 3e c0 rjmp .+124 ; 0x82 <__bad_interrupt>
6: 3d c0 rjmp .+122 ; 0x82 <__bad_interrupt>
8: 3c c0 rjmp .+120 ; 0x82 <__bad_interrupt>
a: 3b c0 rjmp .+118 ; 0x82 <__bad_interrupt>
c: 3a c0 rjmp .+116 ; 0x82 <__bad_interrupt>
e: 39 c0 rjmp .+114 ; 0x82 <__bad_interrupt>
10: 38 c0 rjmp .+112 ; 0x82 <__bad_interrupt>
12: 37 c0 rjmp .+110 ; 0x82 <__bad_interrupt>
14: 76 c0 rjmp .+236 ; 0x102 <__vector_10> <=== Оно!
16: 35 c0 rjmp .+106 ; 0x82 <__bad_interrupt>
18: 34 c0 rjmp .+104 ; 0x82 <__bad_interrupt>
1a: 33 c0 rjmp .+102 ; 0x82 <__bad_interrupt>
1c: 32 c0 rjmp .+100 ; 0x82 <__bad_interrupt>
1e: 31 c0 rjmp .+98 ; 0x82 <__bad_interrupt>
20: 30 c0 rjmp .+96 ; 0x82 <__bad_interrupt>
22: 2f c0 rjmp .+94 ; 0x82 <__bad_interrupt>
24: 2e c0 rjmp .+92 ; 0x82 <__bad_interrupt>
26: 2d c0 rjmp .+90 ; 0x82 <__bad_interrupt>
28: 2c c0 rjmp .+88 ; 0x82 <__bad_interrupt>
2a: 2b c0 rjmp .+86 ; 0x82 <__bad_interrupt>
2c: 2a c0 rjmp .+84 ; 0x82 <__bad_interrupt>
2e: 29 c0 rjmp .+82 ; 0x82 <__bad_interrupt>
30: 28 c0 rjmp .+80 ; 0x82 <__bad_interrupt>
32: 27 c0 rjmp .+78 ; 0x82 <__bad_interrupt>
PS: Чтоб избежать лишних вопросов о версии gcc, отвечу сразу -- самосборная под линухом, версия 4.2.2. В контроллер не заливал, ограничился (пока) статическим анализом, т.ч. если не будет работать, отпишите, не сочтите за труд.
PPS: Попытавшись реализовать вариацию на тему стратегий от Александреску, обломался. Не так-то легко провернуть подобное в случае шаблонного класса. Если у кого-то есть идеи, как реализовать подобное в шаблонном классе, буду очень признателен за подобное. Вопрос интересует только в контексте
полного отсутствия виртуальных методов! С виртуальными методами это тривиально...