在使用GCC进行编译时,通过使用msp430fr*.h
属性标记ISR来定义ISR,该属性具有在__attribute__ ((interrupt(TIMER2_A1_VECTOR)))
void TIMER2_A1_ISR (void) { ... }
标头中定义的向量编号,该标头随TI分发的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
但是,在使用LLVM / Clang进行编译并使用GCC进行汇编和链接时
../../src/main.c:80:17: error: 'interrupt' attribute parameter 38 is out of bounds
__attribute__ ((interrupt(TIMER2_A1_VECTOR)))
^ ~~~~~~~~~~~~~~~~
以上导致编译时错误:
handleMSP430InterruptAttr
答案 0 :(得分:4)
来自clang的错误是由于中断向量编号的硬编码限制为偶数且低于tools/clang/lib/Sema/SemaDeclAttr.cpp
中__isr_6
的30。
但是,即使忽略这一点,来自TI的GCC链接器脚本与Clang不兼容,因为Clang与GCC不同,不生成向量的部分,它只生成符号(别名),如interrupt(12)
为 VECT38 : ORIGIN = 0xFFDA, LENGTH = 0x0002
...
__interrupt_vector_38 : {
KEEP (*(__interrupt_vector_38))
KEEP (*(__interrupt_vector_timer2_a1))
} > VECT38
。链接器脚本发布在
TI GCC分布在各个部分上运行,如下:
interrupt
我们为向量定义一个符号,并将其放在它自己的部分中,该链接脚本需要它。我们仍然需要#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
属性,因为它使用正确的调用约定标记ISR函数等。数字可以是哑,0,重用是好的,Clang后缀它生成的别名。 (在此解决方案中,Clang定义的每个别名符号的2个字节被浪费了。)
print "some string"+some_int