【问题标题】:#pragma inside #define#pragma 内 #define
【发布时间】:2010-07-27 05:20:49
【问题描述】:

我正在使用 C 语言在微控制器中工作。在这个特定的 micro 中,必须使用#pragma 通过以下方式定义中断:

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

&lt;interrupt_address&gt; 是向量表中的中断地址。 &lt;interrupt_category&gt; 是 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)(); }

我猜预处理器指令不能在#defines 中使用?有什么解决办法吗?

【问题讨论】:

  • 什么微控制器和编译器?如果它是基于 GCC 的,可能会有一个特殊的属性宏可以使用,比如在 Microchip 的 C32 中:void __ISR(_TIMER_5_VECTOR) SomeISR(void)
  • micro是OKI 431,编译器来自OKI:IDEU8。

标签: c c-preprocessor microcontroller


【解决方案1】:

C99 具有新的 _Pragma 关键字,可让您将 #pragma 放置在宏中。基本上,它需要一个字符串作为参数,该参数对应于您将提供给 #pragma 指令的文本。

如果您的编译器不支持此功能(gcc 支持)并且您会寻求所需的外部实现(如前所述,m4 可能是一个选择),那么最好的可能是保持尽可能接近可能对那个不那么新的_Pragma。然后,一旦您的编译器构建器赶上了标准,您就可以停止使用您的脚本。

【讨论】:

  • 编译器不支持_Pragma。 :(
  • @Donotalo,太糟糕了。距此标准仅存在 11 年 ;-) 您可以尝试混合解决方案,仅使用 gcc 作为预处理器,然后使用您的本机编译器进行后续编译阶段。
【解决方案2】:

一种解决方法是使用代码生成或其他宏语言来预处理您的代码。

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

让您的 makefile 或类似文件调用宏语言(例如 m4)或某种形式的脚本来生成 .c 文件

然后编译它。

【讨论】:

  • 正在寻找不会调用其他脚本的解决方案。
【解决方案3】:

据我所知,您具体要求的内容是不可能的。我假设一个与GNU C Preprocessor 相同的预处理器。在手册中,it states:

编译器不会重新标记预处理器的输出。每个预处理标记成为一个编译器标记。

【讨论】:

  • 我也觉得不可能。但我想知道是否有其他方法可以实现。
猜你喜欢
  • 1970-01-01
  • 2011-10-01
  • 1970-01-01
  • 2015-06-20
  • 1970-01-01
  • 2011-07-31
  • 2020-05-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多