2

GCC でコンパイルする場合、ISR は、TI が配布する GCC ツールチェーンに同梱されているヘッダーでinterrupt定義されたベクトル番号を持つ属性でマークすることによって定義されます。msp430fr*.h

__attribute__ ((interrupt(TIMER2_A1_VECTOR)))
void TIMER2_A1_ISR (void) { ... }

ただし、LLVM/ClangでコンパイルしてGCCでアセンブル・リンクすると

clang -emit-llvm -c -MD --target=msp430 -D__MSP430FR5969__ -nobuiltininc -nostdinc++ -isysroot /none -O1 -g -std=c99 -pedantic -Wall -I /opt/ti/msp430-gcc/lib/gcc/msp430-elf/4.9.1/include -I /opt/ti/msp430-gcc/msp430-elf/include -I /opt/ti/msp430-gcc/include -I ../src  -DBOARD_MSP_TS430  ../../src/main.c -o main.bc

上記はコンパイル時エラーを引き起こします:

../../src/main.c:80:17: error: 'interrupt' attribute parameter 38 is out of bounds
__attribute__ ((interrupt(TIMER2_A1_VECTOR)))
            ^         ~~~~~~~~~~~~~~~~
4

1 に答える 1

4

clang からのエラーは、割り込みベクトル番号が偶数で 30 未満であるというハードコーディングされた制限によるものhandleMSP430InterruptAttrですtools/clang/lib/Sema/SemaDeclAttr.cpp

しかし、これを無視しても、TI の GCC を使用したリンカー スクリプトは Clang と互換性がありません。Clang は GCC とは異なり、ベクトルのセクションを生成せず、for のようなシンボル (エイリアス) のみを生成する__isr_6ためinterrupt(12)です。TI GCC ディストリビューションに同梱されているリンカー スクリプトは、次のようにセクションで動作します。

 VECT38           : ORIGIN = 0xFFDA, LENGTH = 0x0002
 ...
 __interrupt_vector_38  : {
     KEEP (*(__interrupt_vector_38))
     KEEP (*(__interrupt_vector_timer2_a1))
 } > VECT38

ベクターのシンボルを定義し、リンカー スクリプトが必要とする名前の独自のセクションに配置します。適切な呼び出し規約などで ISR 関数をマークするため、属性はまだ必要ですinterrupt。番号はダミー、0、再利用は問題ありません。Clang は生成するエイリアスに接尾辞を付けます。(このソリューションでは、Clang によって定義されたエイリアス シンボルごとに 2 バイトが無駄になります。)

#ifdef __clang__
__attribute__ ((interrupt(0)))
#else
__attribute__ ((interrupt(TIMER2_A1_VECTOR)))
#endif
void TIMER2_A1_ISR (void)
{  ... }  
#ifdef __clang__
__attribute__ ((section("__interrupt_vector_timer2_a1"),aligned(2)))
void (*__vector_timer2_a1)(void) = TIMER2_A1_ISR;
#endif
于 2015-10-21T17:57:35.670 に答える