Core-Local Interrupt Controller (CLIC) — это контроллер прерываний, разработанный специально для архитектуры RISC-V. Он представляет собой расширение привилегированной архитектуры, которое обеспечивает гибкие и эффективные механизмы управления прерываниями.
На момент середины 2025 года спецификация CLIC не ратифицирована -
Fast Interrupts, в связи с чем функционал CLIC всё ещё дорабатывается и изменяется (работа ведется в репозитории
riscv-fast-interrupt). Таким образом при работе с контроллером CLIC требуется точно знать версию спецификации, на основании которой был разработан контроллер.
В МК MDR1206(A)FI и MDR1215LGI реализован контроллер CLIC на основе спецификации
"Smclic" Core-Local Interrupt Controller (CLIC) RISC-V Privileged Architecture Extension", версия 0.9-12/21/2021. Подробное описание данной версии контроллера CLIC приведено в спецификации микроконтроллер.
В данной статье рассмотрены особенности работы с контроллером прерываний CLIC, реализованном в МК MDR1206(A)FI и MDR1215LGI, а также описаны особенности работы с CLIC при использовании библиотеки MDR32VF0xI.
Содержание
1. Ключевые особенности CLIC
CLIC спроектирован как улучшение базовой системы прерываний RISC-V, которое интегрируется непосредственно в ядро, заменяя часть базового функционала.
Основные особенности CLIC:
- Режимы привилегированности: для каждого прерывания можно настроить, в каком режиме привилегированности будет выполняться его обработчик - в режиме Machine (M) или User (U).
- Режим захвата прерывания: захват входного сигнала прерывания может быть настроен программно - по уровню (высокому/низкому) или по фронту (положительному/отрицательному). Этот функционал позволяет настраивать CLIC для работы с различными типами периферийных устройств.
- Векторизация прерываний: поддерживается как обработка прерываний с помощью общего обработчика, так и векторная обработка прерываний. Настройка векторизации выполняется индивидуально для каждого прерывания.
- Приоритет и уровень прерывания: каждому прерыванию можно программно назначить приоритет и уровень прерывания. Количество доступных приоритетов и уровней конфигурируется программно.
- Вытеснение прерываний: текущий обработчик прерывания может быть прерван (вытеснен) новым прерыванием, которое имеет более высокий уровень прерывания.
2. Программная конфигурация CLIC
Обширные возможности CLIC неизбежно приводят к повышенной сложности его программной настройки. Помимо настройки каждого отдельного прерывания, разработчику также требуется выполнить глобальную настройку CLIC.
2.1 Глобальные настройки CLIC
Первоначально требуется настроить глобальные настройки CLIC, которые применимы ко всем прерываниям, а именно:
- количество режимов привилегированности (M или M/U): поле nmbits в регистре cliccfg;
- количество уровней прерываний (и соответственно приоритетов): поле nlbits в регистре cliccfg;
- адрес общего обработчика прерываний и исключений: CSR-регистр mtvec/utvec;
- адрес таблицы обработчиков прерываний: CSR-регистр mtvt/utvt;
- пороговый уровень прерываний: CSR-регистр mintthresh/uintthresh (по сбросу разрешены все прерывания);
- глобальное разрешение прерываний: бит mie/uie в CSR-регистре mstatus/ustatus.
2.2 Индивидуальные настройки прерываний в CLIC
Каждому прерыванию
i соответствует набор из 4-х регистров, позволяющих установить:
- состояние прерывания: регистр clicintip[i] (программное изменение доступно только для захвата по фронту);
- разрешение прерывания: регистр clicintie[i];
- режим привилегированности (M или U): поле mode в регистре clicintattr[i];
- режим захвата прерывания (уровень или фронт, полярность): поле trig в регистре clicintattr[i];
- векторизацию прерывания: бит shv в регистре clicintattr[i];
- уровень и приоритет прерывания: поле clicintctl в регистре clicintctl[i].
3. Режим захвата входного сигнала прерывания
Для работы с различными типами периферийных устройств CLIC позволяет для каждого прерывания индивидуально настроить режим захвата сигнала прерывания. Данная настройка осуществляется в поле
trig регистра
clicintattr[i] и реализует 4 варианта, при которых сигнал прерывания считается активным:
- по высокому уровню;
- по низкому уровню;
- по положительному фронту;
- по отрицательному фронту.
Важно отметить, что прерывания, выбранные для работы по уровню, должны обеспечивать активное состояние сигнала прерывания до тех пор, пока прерывание не будет взято в обработку. То есть такие прерывания должны сбрасываться программно в обработчике прерывания. Если сигнал прерывания может быть сброшен аппаратно до входа в обработчик прерывания, то для такого прерывания необходимо выбирать захват по фронту, иначе запрос может не успеть взяться в обработку и будет пропущен.
В МК MDR1206(A)FI и MDR1215LGI все прерывания, кроме DMA, EXT_INTx и системного таймера, рекомендуется настраивать в режим захвата по высокому уровню. Прерывания от DMA и системного таймера рекомендуется настраивать в режим захвата по положительному фронту. Настройка прерывания от EXT_INTx зависит от внешнего устройства, которое формирует сигнал прерывания:
- если сигнал прерывания гарантированно удерживается до входа в обработчик прерывания, то может быть настроен режим захвата по уровню или фронту;
- если сигнал прерывания может сброситься до входа в обработчик прерывания, то должен быть настроен режим захвата по фронту.
4. Векторизация прерываний
Согласно спецификации RISC-V (
The RISC-V Instruction Set Manual Volume I: Unprivileged Architecture), аппаратные события, прерывающие нормальный поток выполнения, делятся на две категории:
- исключения (exceptions): возникают во время выполнения инструкции (например, ошибочный доступ по невыровненному адресу, исполнение инструкции ecall и т.д.);
- прерывания (interrupts): вызываются внешним асинхронным событием (например, запрос прерывания от периферийного устройства).
При возникновении исключения управление всегда передается общему обработчику. При возникновении прерываний обработка будет зависеть от настройки режима векторизации в CLIC:
- невекторные прерывания: управление передается общему обработчику;
- векторные прерывания: управление передается индивидуальному обработчику согласно таблице векторов прерываний.
4.1 Обработка исключений и невекторных прерываний
При возникновении исключения или невекторного прерывания управление передается общему обработчику. Адрес общего обработчика устанавливается в поле
BASE CSR-регистра
mtvec/utvec. Настройка прерывания
i в невекторный режим работы осуществляется в регистре
clicintattr[i], бит
shv = 0. В общем обработчике необходимо предусмотреть алгоритмы обработки исключений и прерываний. Спецификация RISC-V предполагает выполнение обработки с помощью анализа CSR-регистра
mcause/ucase, в котором хранятся:
- тип события (исключение или прерывание);
- номер события (номер исключения/прерывания).
После определения события дальнейшая обработка может быть выполнена любым требуемым способом, однако для универсальности, как правило, реализуется программный трамплин, который на основании номера события и таблиц векторов исключений и прерываний вызывает соответствующий обработчик. Для случая реализации программного трамплина в CLIC предусмотрен CSR-регистр
mnxti/unxti, который позволяет ускорить передачу управления обработчику прерывания. При этом реализация программного трамплина для исключений остается с использованием
mcause/ucase.
Для работы с
mnxti/unxti необходимо предварительно определить таблицу векторов прерываний и записать её адрес в CSR-регистр
mtvt/utvt. При чтении CSR-регистра
mnxti/unxti выполняется аппаратный поиск подходящего ожидающего прерывания:
- прерывание найдено: чтение возвращает адрес соответствующего обработчика из таблицы векторов прерываний (mtvt/utvt);
- прерывание не найдено: чтение возвращает 0.
Активное прерывание считается подходящим к обработке, если выполнены все следующие условия:
- прерывание работает в невекторном режиме;
- прерывание имеет текущий уровень привилегированности (горизонтальное прерывание);
- прерывание имеет уровень больше, чем пороговый уровень, заданный в CSR-регистре mintthresh/uintthresh;
- прерывание имеет уровень больше, чем предыдущий уровень прерывания (хранится в CSR-регистре mcause.pil/ucause.pil).
Если имеется несколько подходящих прерываний, то очередность обработки определяется уровнем и приоритетом прерывания. Подробнее в
разделе 5.
Немного остановимся на последнем пункте про предыдущий уровень прерывания. Значение в
mcause.pil/ucause.pil обновляется только при аппаратном вызове обработчика прерывания. Если работа выполняется без горизонтального вытеснения и в рамках одного режима привилегированности, то вход в общий обработчик всегда будет осуществляться из основного потока, который имеет уровень прерывания 0. Таким образом все прерывания с уровнем 1 и более будут иметь уровень больше, чем предыдущий уровень прерывания (основного потока).
При работе с горизонтальным вытеснением прерываний при чтении CSR-регистра
mnxti/unxti будут возвращаться только прерывания, уровень которых больше, чем основной поток (0) или вытесненное прерывание.
Схематично обработка исключений и невекторных прерываний в M-режиме показана на рисунке 1.

Рисунок 1 - Обработка исключений и невекторных прерываний в M-режиме
4.2 Обработка векторных прерывания
Векторный режим работы прерывания
i устанавливается в регистре
clicintattr[i], бит
shv = 1. При возникновении векторного прерывания из таблицы векторов прерываний аппаратно считывается адрес соответствующего обработчика прерывания, после чего ему передается управление. Ключевое преимущество данного подхода - минимальная задержка до начала выполнения обработчика прерывания, так как полностью исключается этап программной векторизации прерываний.
Схематично обработка векторных прерываний в M-режиме показана на рисунке 2.

Рисунок 2 - Обработка векторных прерываний в M-режиме
5. Уровни, приоритеты и вытеснение прерываний
В ряде приложений требуется обрабатывать сразу несколько прерываний от различных периферийных блоков и с разными режимами привилегированности. При этом для части прерываний может быть критически важным время начала обработки, поэтому такие прерывания должны обрабатываться в первую очередь. Для соответствия требованиям приложения CLIC реализует гибкую систему диспетчеризации прерываний, позволяющую выстроить необходимую очередность выполнения обработчиков прерывания.
Для настройки очередности выполнения обработчиков прерывания CLIC предоставляет следующие настройки:
- количество доступных уровней и приоритетов прерываний: регистре cliccfg, поле nlbits;
- режим привилегированности: регистр clicintattr[i], поле mode;
- уровень прерывания: регистр clicintctl[i], поле level;
- приоритет прерывания: регистр clicintctl[i], поле priority;
- разрешение вытеснения горизонтальных прерываний: пролог/эпилог обработчика прерывания.
Для немедленной обработки высокоранговых прерываний CLIC поддерживает механизм вытеснения прерываний, позволяющий прерывать выполнение текущего обработчика. CLIC поддерживает два типа вытеснений:
- вертикальные: прерывания с разными режимами привилегированности. Прерывание более высокого привилегированного режима (например, M-режима) всегда вытесняет обработчик более низкого режима (U-режима), независимо от уровня прерывания.
- горизонтальные: прерывания с разными уровнями в рамках одного режима привилегированности. Прерывание с более высоким уровнем вытесняет активный обработчик с более низким уровнем.
Вертикальные вытеснения разрешены всегда, при этом разрешение горизонтальных прерываний настраивается программно для каждого обработчика прерывания.
Очередность выполнения обработчиков прерывания в рамках одного режима привилегированности определяется уровнем и приоритетом прерывания. Сначала проверяется уровень прерывания (прерывания с большим уровнем выполняются в первую очередь), если уровни прерываний одинаковые, то далее проверяется приоритет (прерывания с большим приоритетом выполняются в первую очередь). Горизонтальные вытеснения прерываний определяются только на основании уровня прерываний, приоритет не оказывает влияния на вытеснение.
Важно отметить, что CLIC позволяет комбинировать использование невекторных и векторных прерываний с индивидуальной настройкой горизонтальных вытеснений.
При обработке вертикальных вытеснений для разных режимов привилегированности рекомендуется использовать разные стеки для избежания проблем с уязвимостями безопасности. Для хранения указателя стека при переключении между режимами привилегированности предусмотрены регистры xscratch, а также опциональные регистры xscratchcsw и xscratchcsw1.
5.1 Настройка уровней и приоритетов прерывания
CLIC предоставляет настройку количества приоритетов и уровней прерывания. Суммарно под поля настройки приоритетов и уровней прерывания i в регистре
clicintctl[i] выделяется до 8 бит в зависимости от аппаратной реализации. Количество реализованных бит в регистре
clicintctl[i] указывается в регистре
clicinfo, поле
clicintctlbits. Далее в регистре
cliccfg с помощью поля
nlbits программно настраивается граница полей приоритетов и уровней, которая определяет, сколько бит выделяется для настройки уровней, при этом оставшиеся реализованные биты в
clicintctl[i] выделяются для настройки приоритета (
clicintctlbits - nlbits).
Наглядно данная настройка представлена на рисунке 3.

Рисунок 3 - Распределение полей приоритетов и уровней прерывания в регистре
clicintctl[i]
Например, в MDR1206(A)FI в регистре
clicintctl[i] реализовано 4 бита (
clicintctlbits), таким образом для приоритетов и уровней прерывания суммарно доступно 2
4 = 16 вариантов. В регистре
cliccfg с помощью поля nlbits устанавливается количество бит для настройки уровней прерывания, при этом:
- количество уровней прерывания: 2nlbits;
- количество приоритетов прерываний: 2(clicintctlbits - nlbits).
Например, если установить
nlbits = 2, то количество уровней и приоритетов будет равное - по 4 варианта.
5.2 Обработка невекторных и векторных прерываний без использования горизонтальных вытеснений
В соответствии со спецификацией RISC-V по умолчанию реализован механизм обработки прерываний без горизонтальных вытеснений - при входе в обработчик прерывания сбрасывается бит глобального разрешения прерываний
mie/uie в CSR-регистре
mstatus/ustatus, новые прерывания от текущего режима привилегированности запрещаются. Таким образом в рамках одного уровня привилегированности прерывания выполняются поочередно, при этом для нескольких активных прерываний выбор очередности основывается на уровне и приоритете прерываний. При этом сначала проверяется уровень прерывания, а затем, если уровни равны, то приоритет прерывания.
Схематично обработка прерываний без использования горизонтальных вытеснений приведена на рисунке 4.

Рисунок 4 - Обработка прерываний без использования горизонтальных вытеснений
Пояснения к рисунку 4:
- (1): вызов общего обработчика от IT2, вызов обработчика IT2;
- (2): вызов обработчика IT3, т.к. уровень IT3 (уровень 2) выше, чем уровень IT1 (уровень 1);
- (3): вызов общего обработчика от IT1;
- (4): вызов обработчика IT2, т.к. уровни одинаковые, но приоритет IT2 (приоритет 3) выше, чем приоритет IT1 (приоритет 2);
- (5): вытеснение обработчиком IT4 обработчика IT2, т.к. IT4 работает в M-режиме, а IT2 в U-режиме;
- (6): вызов обработчика IT1 без выхода из общего обработчика.
5.3 Обработка невекторных и векторных прерываний с использованием горизонтальных вытеснений
Разрешение горизонтальных вытеснений осуществляется программным путем с помощью изменения пролога и эпилога обработчика прерывания.
По умолчанию горизонтальные прерывания выключены. Это связано с тем, что при вызове обработчика прерывания часть контекста прерванного потока аппаратно сохраняется в CSR-регистры m
epc/uepc и
mcause/ucause. Данные регистры не имеют аппаратного стека, поэтому вызов нового более высокоуровневого прерывания перезапишет эти регистры и контекст будет потерян. В связи с этим при вызове обработчика прерывания горизонтальные вытеснения запрещаются путем аппаратного сброса бита глобального разрешения прерываний
mie/uie.
Чтобы включить горизонтальные вытеснения, в конце пролога обработчика прерывания требуется программно сохранить в стек CSR-регистры mepc/uepc и
mcause/ucause, после чего разрешить глобальные прерывания. Перед выходом из обработчика прерывания в начале эпилога требуется запретить глобальные прерывания, после чего восстановить CSR-регистры mepc/uepc и
mcause/ucause из стека.
Горизонтальные вытеснения прерываний определяются только на основании уровня прерываний. Если уровни прерываний равны, то обработчики прерываний выполняются поочередно на основании приоритета.
Схематично обработка прерываний с использованием горизонтальных вытеснений приведена на рисунке 5.

Рисунок 5 - Обработка прерываний без использования горизонтальных вытеснений
Пояснения к рисунку 5:
- (1): вызов общего обработчика от IT2, вызов обработчика IT2;
- (2): вытеснение обработчиком IT3 обработчика IT2, т.к. уровень IT3 (уровень 3) выше, чем уровень IT2 (уровень 2);
- (3): вызов обработчика IT1 без выхода из общего обработчика, т.к. уровень IT1 (уровень 1) больше, чем предыдущий уровень прерывания (основной поток, mcause.pil = 0);
- (4): вытеснение общим обработчиком от IT2 обработчика IT1, т.к. уровень IT2 (уровень 2) выше, чем уровень IT1 (уровень 1), далее вызов обработчика IT2;
- (5): вытеснение обработчиком IT4 обработчика IT2, т.к. IT4 работает в M-режиме, а IT2 в U-режиме.
6. Особенности работы с CLIC при использовании библиотеки MDR32VF0xI
Для доступа к настройке прерываний необходимо подключить заголовочный файл
system_MDR32VF0xI_it.h. Весь функционал по управлению прерываниями расположен в двух программных компонентах:
- CMSIS::CoreSupport::core_clic: платформонезависимый драйвер контроллера прерываний CLIC, содержит функции для настройки контроллера CLIC;
- CMSIS::DeviceSupport::system_MDR32VF0xI_it: платформозависимый драйвер прерываний, содержит функции глобального управления прерываниями, общий обработчик исключений/прерываний и заглушки обработчиков прерываний/исключений.
В MDR32VF0xI вер. 0.2.0 для CLIC реализована поддержка прерываний, работающих только в M-режиме.
6.1 Базовая конфигурация CLIC в SystemInit()
Базовая конфигурация контроллера прерываний CLIC может быть выполнена перед началом исполнения основной программы в функции
SystemInit(). Включение конфигурация CLIC и установка параметров настройки выполняется в config-файле:
- MDR32VF0xI_config.h, если используется SPL+CMSIS (по умолчанию);
- system_MDR32VF0xI_config.h, если используется только CMSIS.
По умолчанию в
MDR32VF0xI_config.h/system_MDR32VF0xI_config.h включена конфигурация CLIC в
SystemInit() со следующими параметрами (макроопределение
CLIC_SYSTEM_INIT раскомментировано):
- глобальные настройки CLIC:
- количество режимов привилегированности (CLIC_SYSTEM_INIT_PRIVILEGE_LEVELS): только M-режим;
- количество уровней и приоритетов (CLIC_SYSTEM_INIT_MAX_LEVELS): 4 уровня и 4 приоритета прерываний;
- индивидуальные настройки для всех прерываний:
- разрешение: все прерывания выключены;
- режим привилегированности (CLIC_SYSTEM_INIT_VECTOR_MODE_IRQ): все прерывания работают в M-режиме;
- режим захвата (CLIC_SYSTEM_INIT_TRIGGER_IRQ): все прерывания, кроме DMA, настроены в режим захвата по высокому уровню, DMA - в режим захвата по положительному фронту;
- векторизация (CLIC_SYSTEM_INIT_VECTOR_MODE_IRQ): все прерывания работают в векторном режиме;
- уровень и приоритет: все прерывания имеют уровень 1 и приоритет 1.
Независимо от включения базовой конфигурации CLIC (макроопределение
CLIC_SYSTEM_INIT) в
SystemInit() всегда выполняются следующие настройки:
- установка адреса общего обработчика прерываний и исключений для M-режима;
- установка адреса таблицы обработчиков прерываний для M-режима;
- глобальное разрешение прерываний для M-режима.
После базовой конфигурации CLIC в основной программе можно использовать функции из драйвера
core_clic для настройки отдельных параметров прерываний, аналогично работе с контроллером NVIC в системах с ARM-ядром. Настройка глобальных и индивидуальных для прерываний параметров CLIC также может быть произведена с использованием структур инициализации:
- CLIC_Init() с использованием структуры инициализации CLIC_InitTypeDef для настройки глобальных параметров CLIC;
- CLIC_InitIRQ() с использованием структуры инициализации прерывания CLIC_IRQ_InitTypeDef для индивидуальной настройки прерывания.
6.2 Определение обработчиков прерывания в зависимости от режима векторизации и горизонтального вытеснения
Помимо конфигурации контроллера CLIC требуется также по-разному определять обработчики прерываний в зависимости от режима векторизации и вытеснения.
В отличие от обычной функции, обработчик прерывания, который аппаратно вызывается при возникновении прерывания, должен содержать расширенный пролог/эпилог для сохранения/восстановления дополнительных регистров ядра, а также специальную инструкцию возврата из обработчика прерывания -
mret/uret вместо
ret.
Компиляторы GCC/IAR реализуют модификацию обычной функции в обработчик прерывания с помощью указания атрибута
interrupt, при этом в таком обработчике горизонтальные вытеснения будут запрещены. Чтобы разрешить горизонтальные вытеснения, требуется дополнительно модифицировать пролог/эпилог обработчика, добавив сохранение/восстановление дополнительных CSR-регистров, хранящих часть контекста прерванного потока, и разрешение/запрещение глобальных прерываний.
Для абстрагирования от компилятора в библиотеку
MDR32VF0xI введены следующие макроопределения (
core_compiler.h и
system_MDR32VF0xI_it.h):
- __INTERRUPT_MACHINE: атрибут обработчика прерывания, работающего в M-режиме без горизонтального вытеснения;
- __INTERRUPT_USER: атрибут обработчика прерывания, работающего в U-режиме без горизонтального вытеснения;
- __INTERRUPT_PREEMPTIBLE(): определение обработчика прерывания, работающего с горизонтальным вытеснением без привязки к режиму привилегированности;
- __DECLARE_INTERRUPT_MACHINE_PREEMPTIBLE(): объявление обработчика прерывания, работающего в M-режиме c горизонтальным вытеснением;
- __DECLARE_INTERRUPT_USER_PREEMPTIBLE(): объявление обработчика прерывания, работающего в U-режиме c горизонтальным вытеснением.
Важно отметить, что данные макроопределения должны применяться только для обработчика, который аппаратно вызывается при возникновении прерывания.
Для невекторного режима - это общий обработчик прерываний и исключений
Trap_IRQHandler(). Индивидуальные обработчики невекторных прерываний должны быть указаны без атрибута, так как они вызываются программно из
Trap_IRQHandler().
Напротив, индивидуальные обработчики векторных прерываний должны быть обязательно указаны с требуемыми вышеуказанными макроопределениями.
По умолчанию определяемые имена обработчиков должны соответствовать именам, указанным в таблицах прерываний и исключений из файла system_MDR32VF0xI_it.с. При необходимости требуемый вектор в таблицах прерываний и исключений может быть перезаписан.
6.2.1 Невекторный режим работы прерываний
Пример определения невекторного обработчика прерывания UART1 в M/U-режиме без привязки к горизонтальному вытеснению приведен в фрагменте кода 1.
Фрагмент кода 1 - Определение невекторного обработчика прерывания UART1 в M/U-режиме без привязки к горизонтальному вытеснению
void UART1_IRQHandler(void)
{
// Some code.
}
Настройка вытеснения прерываний, работающих в невекторном режиме, выполняется в
MDR32VF0xI_config.h/system_MDR32VF0xI_config.h с помощью макроопределения
CLIC_TRAP_MACHINE_PREEMPTIBLE:
- CLIC_TRAP_MACHINE_PREEMPTIBLE закомментировано (по умолчанию): вытеснение прерываний, работающих в невекторном режиме, запрещено;
- CLIC_TRAP_MACHINE_PREEMPTIBLE раскомментировано: вытеснение прерываний, работающих в невекторном режиме, разрешено.
6.2.2 Векторный режим работы прерываний
Пример определения векторного обработчика прерывания UART1 в M-режиме с запретом горизонтального вытеснения приведен в фрагменте кода 2.
Фрагмент кода 2 - Определение векторного обработчика прерывания UART1 в M-режиме с запретом горизонтального вытеснения
__INTERRUPT_MACHINE void UART1_IRQHandler(void)
{
// Some code.
}
Пример определения векторного обработчика прерывания UART1 в M-режиме с разрешением горизонтального вытеснения приведен в фрагменте кода 3.
Фрагмент кода 3 - Определение векторного обработчика прерывания UART1 в M-режиме с разрешением горизонтального вытеснения
__INTERRUPT_PREEMPTIBLE(UART1_IRQHandler)(void)
{
// Some code.
}
__DECLARE_INTERRUPT_MACHINE_PREEMPTIBLE(UART1_IRQHandler);
В одном файле обработчик прерываний с разрешением горизонтального вытеснения сначала определяется c макроопределением `
__INTERRUPT_PREEMPTIBLE()`, а затем объявляется c макроопределением
__DECLARE_INTERRUPT_MACHINE_PREEMPTIBLE()/__DECLARE_INTERRUPT_USER_PREEMPTIBLE(). Аналогичные примеры приведены в библиотеке
MDR32VF0xI, файл
system_MDR32VF0xI_it.h.