Я работаю в микроконтроллере с помощью языка C. В этом конкретном микро, прерывания должны быть определены с помощью #pragma
следующим способом:
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? Есть ли вокруг какая-либо работа?
В C99 есть новое ключевое слово _Pragma
, которое позволяет размещать #pragma
внутри макросов. Обычно он ожидает строку в качестве аргумента, который соответствует тексту, который вы должны передать директиве #pragma
.
Если ваш компилятор не поддерживает это (gcc поддерживает), и вы бы выбрали внешнюю реализацию того, что вам нужно (как сказано, m4
может быть выбором), лучше всего, вероятно, будет оставайтесь как можно ближе к не очень новому _Pragma
. Затем, как только ваш конструктор компилятора догонит стандарт, вы можете просто прекратить использовать свой скрипт.
Насколько мне известно, то, что вы конкретно просите, невозможно. Я предполагаю, что препроцессор работает так же, как Препроцессор GNU C . В руководстве для этого указано :
Компилятор не повторно токенизирует вывод препроцессора. Каждый токен предварительной обработки становится одним токеном компилятора.
Выход - использовать генерацию кода или другой макроязык для предварительной обработки кода.
т.е. писать код с другим расширением.
Пусть ваш makefile или подобная программа вызовет макроязык (например, m4) или скрипт какой-либо формы для создания .c-файла
Затем скомпилируйте его.