Программирование DSP VisualDSP: функции установки обработчиков прерываний Blackfin Mon, December 09 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.


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.

[Ссылки]

1. ADSP-BF538: обработка событий (прерывания, исключения).

 

Добавить комментарий


Защитный код
Обновить

Top of Page