如何使用LLVM / Clang + GCC为MSP430定义中断服务程序?

时间:2015-10-21 17:57:36

标签: clang llvm interrupt msp430 mspgcc

在使用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

1 个答案:

答案 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