2010-07-27 70 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