2010-07-27 71 views
10

我正在使用C语言的微控制器。在这个具体的微,中断必须在下列方式使用#pragma定义:#pragma inside #define

static void func(); 
#pragma INTERRUPT func <interrupt_address> <interrupt_category> 
static void func() { /* function body */ } 

<interrupt_address>是在矢量表中的中断的地址。所述<interrupt_category>是1或2。例如,以限定在端口0引脚0中断:

static void _int_p00(); 
#pragma INTERRUPT _int_p00 0x10 1 
static void _int_p00() { (*isr_p00)(); } 

我们(在本例等isr_p00)限定别处实际中断服务例程和使用函数指针来执行它们。

如果可以使用宏定义中断,那将很方便。我想要做的定义方式如下宏:

#define DECLARE_INTERRUPT(INT_NAME, INT_CAT) \ 
    static void _int_##INT_NAME(); \ 
    #pragma INTERRUPT _int_##INT_NAME INT_NAME##_ADDR INT_CAT \ 
    static void _int_##INT_NAME() { (*isr_##INT_NAME)(); } 

编译器抛出以下错误:

Formal parameter missing after '#' 

说明如下一行:

static void _int_##INT_NAME() { (*isr_##INT_NAME)(); } 

我猜预处理指令不能使用#define s?有什么解决办法吗?

+1

什么是单片机和编译器?如果它是基于GCC的,可能会有一个特殊的属性宏可以使用,如Microchip的C32:void __ISR(_TIMER_5_VECTOR)SomeISR(void)' – detly 2010-07-27 05:36:50

+1

micro是OKI 431,编译器来自OKI:IDEU8。 – Donotalo 2010-07-27 05:42:47

回答

11

C99有新_Pragma关键字,可以让你把#pragma内宏。基本上,它需要一个字符串作为参数,与您要给#pragma指令的文本相对应。如果你的编译器不支持这个(gcc的),你会去外部实现你需要的东西(如说,m4可能是一个选择),最好的可能是尽可能保持接近到那不太新的_Pragma。然后,一旦你的编译器构建器赶上了标准,你可以停止使用你的脚本。

+0

编译器不支持_Pragma。 :( – Donotalo 2010-07-27 08:11:23

+1

@Donotalo,太糟糕了。这个标准只存在11年;-)你可以尝试一个混合解决方案,只需使用'gcc'作为预处理器,然后使用本地编译器进行后续编译阶段。 – 2010-07-27 12:10:10

1

workround是使用代码生成或其他宏语言预处理您的代码。

ie即使用不同的扩展名编写代码。

有你的makefile或类似电话的宏语言(如M4)或某种形式的脚本生成一个.c文件

然后编译。

+0

寻找不会调用其他脚本的解决方案。 – Donotalo 2010-07-27 05:47:04

0

据我所知,你是什么具体是问是不可能的。我假设预处理器的工作原理与GNU C Preprocessor相同。在手册的是,it states

The compiler does not re-tokenize the preprocessor's output. Each preprocessing token becomes one compiler token.

+0

我也认为这是不可能的。但我想知道是否有其他方式可以实现。 – Donotalo 2010-07-27 05:47:22