2010-07-27 46 views
10

Estoy trabajando en un microcontrolador usando el lenguaje C. En este micro específica, las interrupciones tienen que ser definidos usando #pragma en siguiente manera:#pragma dentro #define

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

El <interrupt_address> es la dirección de la interrupción en la tabla vector. El <interrupt_category> es 1 o 2. Por ejemplo, para definir una interrupción en el puerto 0 pin 0:

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

Definimos la rutina de servicio de interrupción real en otro lugar y el puntero de función de uso (como isr_p00 en el ejemplo) para ejecutarlos.

Sería conveniente si las interrupciones se pudieran definir utilizando una macro. Yo quiero hacer definir una macro en la siguiente forma:

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

El compilador lanzar el siguiente error:

Formal parameter missing after '#' 

indicando siguiente línea:

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

supongo directivas del preprocesador no se pueden utilizar en #define s? ¿Hay algún trabajo alrededor?

+1

¿Qué microcontrolador y compilador? Si está basado en GCC, puede haber un atributo especial macro que pueda usarse, como en el C32 de Microchip: 'void __ISR (_TIMER_5_VECTOR) SomeISR (void)' – detly

+1

El micro es OKI 431 y el compilador es de OKI: IDEU8. – Donotalo

Respuesta

11

C99 tiene la nueva _Pragma palabra clave que le permite colocar #pragma macros en su interior. Básicamente, espera una cadena como argumento que corresponda al texto que le habría dado a la directiva #pragma.

Si su compilador no es compatible con esto (lo hace gcc) e iría por una implementación externa de lo que necesita (como dijo, m4 podría ser una opción) lo mejor sería mantenerse lo más cerca posible a ese no tan nuevo _Pragma. Luego, una vez que el compilador compila el estándar, puede dejar de usar su script.

+0

El compilador no es compatible con _Pragma. :( – Donotalo

+1

@Donotalo, lástima.Han pasado 11 años desde que existe este estándar ;-) Podrías probar una solución mixta simplemente usando 'gcc' como preprocesador y luego usando tu compilador nativo para las siguientes etapas de compilación. –

1

Un workround es usar generación de código u otro lenguaje de macros para preprocesar su código.

es decir, escriba el código con una extensión diferente.

Que su makefile o llamada similar el lenguaje de macros (por ejemplo m4) o un guión de alguna forma para generar un archivo .c

A continuación, compile eso.

+0

Buscando una solución que no invocará otro script. – Donotalo

0

Por lo que yo sé, lo que eres específicamente preguntando es imposible. Supongo que hay un preprocesador que funciona igual que el GNU C Preprocessor. En el manual para que, it states:

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

+0

También pensé que era imposible. Pero me pregunto si de alguna otra manera se puede lograr. – Donotalo