2010-07-27 2 views
10

Я работаю в микроконтроллере, используя язык C. В этом конкретном микро, прерывания должны быть определены с помощью #pragma в следующим образом:# прагма внутри #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, может существовать специальный атрибут macro yo, который можно использовать, например, в C32 для Microchip: 'void __ISR (_TIMER_5_VECTOR) SomeISR (void)' – detly

+1

Микро - это OKI 431, а компилятор - из OKI: IDEU8. – Donotalo

ответ

11

C99 имеет новый _Pragma ключевое слово, которое позволяет размещать #pragma внутри макросов. В принципе, он ожидает строку как аргумент, соответствующий тексту, который вы бы указали в директиве #pragma.

Если ваш компилятор не поддерживает это (gcc делает), и вы должны пойти на внешнюю реализацию того, что вам нужно (как сказано, m4 может быть выбором) лучше всего, вероятно, остаться как можно ближе к этому не очень-новому _Pragma. Затем, как только ваш компилятор закроется со стандартом, вы можете просто прекратить использовать ваш скрипт.

+0

Компилятор не поддерживает _Pragma. :( – Donotalo

+1

@Donotalo, слишком плохой.только через 11 лет этот стандарт существует ;-) Вы можете попробовать смешанное решение только с использованием 'gcc' в качестве препроцессора, а затем с помощью собственного компилятора для последующих этапов компиляции. –

1

Рабочим является использование генерации кода или другого языка макросов для предварительной обработки вашего кода.

т. Е. Написать код с другим расширением.

Иметь свой Makefile или подобный вызов макроса языка (например, m4) или скрипт какой-либо форме, чтобы создать файл .c

Затем компилировать что.

+0

Ищете решение, которое не будет вызывать другой скрипт. – Donotalo

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

Смежные вопросы