views:

76

answers:

3

I'm working in a micro controller using C language. In this specific micro, the interrupts have to be defined using #pragma in following way:

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

The <interrupt_address> is address of the interrupt in vector table. The <interrupt_category> is either 1 or 2. For example, to define an interrupt in Port 0 pin 0:

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

We define actual interrupt service routine elsewhere and use function pointer (like isr_p00 in the example) to execute them.

It would be convenient if the interrupts could be defined using a macro. I want do define a macro in following way:

#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)(); }

The compiler throwing the following error:

Formal parameter missing after '#'

indicating following line:

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

I guess preprocessor directives cannot be used in #defines? Is there any work around?

Thanks for your help.

+1  A: 

A workround is to use code generation or another macro language to preprocess your code.

ie write the code with a different extension.

Have your makefile or similar call the macro language (e.g. m4) or a script of some form to generate a .c file

Then compile that.

Mark
Looking for a solution that will not invoke other script.
Donotalo
+1  A: 

As far as I'm aware, what you are specifically asking is impossible. I'm presuming a preprocessor that works the same as the GNU C Preprocessor. In the manual for that, it states:

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

detly
I also thought it is impossible. But I'm wondering if any other way it can be achieved.
Donotalo
+5  A: 

C99 has the new _Pragma keyword that lets you place #pragma inside macros. Basically it expects a string as an argument that corresponds to the text that you would have give to the #pragma directive.

If your compiler doesn't support this (gcc does) and you'd go for an external implementation of what you need (as said, m4 could be a choice) the best would probably be to stay as close as possible to that not-so-new _Pragma. Then once your compiler builder catches up with the standard you could just stop using your script.

Jens Gustedt
The compiler doesn't support _Pragma. :(
Donotalo
@Donotalo, too bad. it is only 11 years now that this standard exists ;-) You could try a mixed solution in just using `gcc` as a preprocessor and then using your native compiler for the subsequent stages of compilation.
Jens Gustedt