VisualDSP: функции установки обработчиков прерываний Blackfin |
![]() |
Добавил(а) microsin |
В составе VisualDSP имеются удобные библиотечные функции для установки обработчиков прерываний (ISR) с заданным приоритетом - register_handler и register_handler_ex, использование которых можно подключить заголовочным файлом sys/exception.h (сами функции определены в модуле Blackfin\lib\src\libc\crt\reghdlr_s.c). После вызова этих функций в таблице векторов прерываний появляются настроенные адреса (вектора прерываний), указывающие на ISR. // Файл Blackfin\lib\src\libc\crt\reghdlr_s.c
/*************************************************************************
** Регистрирует обработчик прерывания (ISR) в таблице векторов прерываний (EVT).
** Вернет предыдущее значение, если ISR уже был назначен.
*/ ex_handler_fn register_handler(interrupt_kind kind, ex_handler_fn fn) { return register_handler_ex(kind, fn, EX_INT_ENABLE); } /*
** Расширенная функция регистрации ISR в EVT.
** Вернет старый ISR.
**
** Если параметр enable == EX_INT_ALWAYS_ENABLE, то установит функцию fn
** (если fn != EX_INT_IGNORE и fn != EX_INT_DISABLE), и затем разрешит
** прерывание через IMASK.
**
** Если fn == EX_INT_iGNORE, то прерывание будет запрещено.
** Если fn == EX_INT_DEFAULT, то из EVT будет удалена ссылка на ISR, и
** прерывание будет запрещено через IMASK.
** Иначе будет установлен новый ISR. Далее,
** если enable == EX_INT_DISABLE, то прерывание будет запрещено через IMASK
** если enable == EX_INT_ENABLE, то прерывание будет разрешено через IMASK
** иначе состояние прерывания останется неизменным.
*/ ex_handler_fn register_handler_ex(interrupt_kind kind, ex_handler_fn fn, int enable) { volatile ex_handler_fn *evt = (volatile ex_handler_fn *)EX_EVENT_VECTOR_TABLE; ex_handler_fn old; if (ik_emulation <= kind && kind <= ik_ivg15) { old = evt[kind]; if (enable == EX_INT_ALWAYS_ENABLE) { // Всегда хочу выйти с разрешенным прерыванием if (fn != EX_INT_IGNORE && fn != EX_INT_DISABLE) { evt[kind] = fn; } enable_int(kind); return old; } if (fn == EX_INT_IGNORE) { disable_int(kind); } else if (fn == EX_INT_DEFAULT) { disable_int(kind); evt[kind] = 0; } else { if (enable == EX_INT_DISABLE) { disable_int(kind); } evt[kind] = fn; if (enable == EX_INT_ENABLE) { enable_int(kind); } } return old; } return EX_INT_IGNORE; } Как можно увидеть из кода функций, отличие register_handler от register_handler_ex состоит только в том, что register_handler является упрощенной - она сама пользуется вызовом функции register_handler_ex. Если при вызове register_handler прерывание на эту запись EVT уже настроено, то ничего не произойдет, иначе будет настроено новое прерывание. У функции register_handler_ex поведение более сложное - можно на выходе запрещать, разрешать прерывания, переназначать обработчик прерывания в EVT. [Ссылки] |