Обработка опоздавшего высокоприоритетного прерывания
В системах реального времени часто возникают ситуации, когда во время перехода
к обработке низкоприоритетного прерывания возникает еще одно прерывание с более высоким приоритетом. Если такая ситуация возникнет еще на фазе загрузки стека, то по его завершении КВВП инициирует переход к обработке высокоприоритетного прерывания. Загрузка стека будет продолжаться еще минимум 6 циклов с момента возникновения высокоприоритетного прерывания, после чего будет выполнена выборка нового адреса процедуры обработки прерывания.
Высокоприоритетное прерывание будет обработано первым, даже если оно возникнет уже на фазе перехода к обработке низкоприоритетного прерывания, при этом, дополнительные операции над стеком будут исключены.
Отложенное низкоприоритетное прерывание будет обработано сразу по завершении обработки высокоприоритетного прерывания с задержкой 6 циклов.
Чтобы включить в работу КВВП необходимо выполнить три действия. Вначале сконфигурировать таблицу векторов используемых прерываний. Затем настроить регистры КВВП с целью активизации и установки уровней приоритета прерываний КВВП. И, наконец, настроить УВВ и разрешить поддержку ими прерываний.
Таблица векторов исключительных ситуаций
Таблица векторов Cortex начинается с нижней части адресного пространства. Однако таблица векторов начинается не с нулевого адреса, а с адреса 0x00000004, т.к. первые четыре байта используются для хранения начального адреса указателя стека.
|
|
Таблица векторов исключительных ситуаций содержит адреса, которые загружаются в счетчик программы, когда ЦПУ переходит в исключительную ситуацию.
Номер | Тип исключительной | Приоритет | Тип приоритета | Описание |
ситуации | ||||
1 | Reset | -3 (высший) | фиксированнный | Сброс |
2 | NMI | -2 | фиксированнный | Немаскируемое |
прерывание | ||||
3 | Hard Fault | -1 | фиксированнный | Обработчик аварийный |
состояний по | ||||
умолчанию, если | ||||
другой не реализован | ||||
4 | MemManageFault | 0 | устанавливаемый | Сбой в блоке защите |
памяти или доступ по | ||||
несуществующему | ||||
адресу | ||||
5 | BusFault | 1 | устанавливаемый | Ошибки в интерфейсе |
AHB | ||||
6 | UsageFault | 2 | устанавливаемый | Исключительные |
ситуации, вызванные | ||||
программными | ||||
ошибками | ||||
7-10 | Reserved | N.A. | N.A. | |
11 | SVCall | 3 | устанавливаемый | Вызов системных |
служб | ||||
12 | DebugMonitor | 4 | устанавливаемый | Точки прерывания, |
контрольные точки, | ||||
внешняя отладка | ||||
13 | Reserved | N.A. | N.A. | |
14 | PendSV | 5 | устанавливаемый | Отправляемый запрос |
системному устройству | ||||
15 | SYSTICK | 6 | устанавливаемый | Срабатывание |
системного таймера | ||||
16 | Прерывание 0 | 7 | устанавливаемый | Внешнее прерывание 0 |
....... | ................................ | .................... | устанавливаемый | ................................ |
256 | Прерывание 240 | 247 | устанавливаемый | Внешнее прерывание |
240 |
Каждый из векторов прерываний занимает 4 байта и указывает на начальный адрес каждой конкретной процедуры обработки прерывания. Первые 15 векторов - адреса обработки исключительных ситуаций, возникающих в ядре Cortex. К ним относятся вектор сброса, немаскируемое прерывание, управление авариями и ошибками, исключительные ситуации отладочной системы и прерывание таймера SysTick. Набором инструкций Thumb-2 также поддерживается инструкция, выполнение которой приводит к генерации исключительной ситуации. Начиная с 16 вектора, следуют адреса обработки прерываний пользовательских УВВ. Их назначение зависит от каждого конкретного производителя. В программе таблица векторов обычно приводится в отдельном файле и содержит адреса процедур обработки прерываний:
|
|
|
|
|
|
AREA RESET, DATA, READONLY
EXPORT __Vectors
__Vectors
DCD __initial_sp
; Верхняя граница стека
DCD Reset_Handler
; Обработчик сброса
DCD NMI_Handler; Обработчик немаскируемого прерывания
DCD HardFault_Handler | ; Обработчик аварий типа HardFault | |
DCD MemManage_Handler ; Обработчик аварий блока защиты памяти | ||
DCD BusFault_Handler | ; Обработчик аварий типа BusFault | |
DCD UsageFault_Handler | ; Обработчик аварий типа UsageFault | |
DCD 0 | ; Резерв | |
DCD 0 | ; Резерв | |
DCD 0 | ; Резерв | |
DCD 0 | ; Резерв | |
DCD SVC_Handler | ; Обработчик программно-сгенерированного | |
Прерывания | ||
DCD DebugMon_Handler | ; Обработчик прерывания встроенной отладочной | |
Системы | ||
DCD 0 | ; Резерв | |
DCD PendSV_Handler | ; Обработчик PendSV | |
DCD SysTick_Handler | ; Обработчик прерывания таймера SysTick |
Например, если используется прерывание таймера SysTick, то объявление на Си процедуры обработки прерывания выполняется следующим образом:
void SysTick_Handler (void) { }
Регистры КВВП находятся в области системных ресурсов Cortex-M3 и доступ к ним возможен при работе ЦПУ только в привилегированном режиме.
Настройка внутренних исключительных ситуаций процессора Cortex выполняется
с помощью регистров системного управления и системных приоритетов, а пользовательских УВВ - с помощью регистров IRQ. Прерывание SysTick является
внутренней исключительной ситуацией процессора Cortex и, поэтому, управляется через системные регистры. Некоторые внутренние исключительные ситуации постоянно разрешены. К ним относятся прерывание по сбросу, немаскированное прерывание, а также и прерывание таймера tSysTick, поэтому, никаких действий с КВВП по разрешению этого прерывания делать не нужно. Для настройки прерывания SysTick нам необходимо активизировать сам таймер и его прерывание с помощью соответствующего регистра управления:
SysTickCurrent = 0x9000; | //Начальное значение счетчика SysTick |
SysTickReload = 0x9000; | //Перезагружаемое значение |
SysTickControl = 0x07; | //Запуск счета и разрешение прерывания |
Приоритет каждой внутренней исключительной ситуации Cortex можно задать в системных регистрах приоритета. У исключительных ситуаций Reset, NMI и hard fault он фиксированный. Этим гарантируется, что ядро всегда будет переходить к обработке известной исключительной ситуации. У всех остальных исключительных ситуаций имеется восьмибитное поле, которое расположено в трех системных регистрах приоритета. МК STM32 используют только 16 уровней приоритета, поэтому, у них активно только 4 бита этого поля. Однако важно запомнить, что приоритет устанавливается четырьмя старшими битами. Каждое пользовательское УВВ управляется через блоки регистров IRQ. У каждого такого УВВ имеется бит разрешения прерывания. Все эти биты находятся в пределах двух 32-битных регистров установки разрешения прерываний. Для отключения источника прерывания предусмотрены отдельные регистры отмены разрешения прерываний. У КВВП также имеются регистры отправленных и активных прерываний, которые позволяют отследить состояние источника прерывания.
У каждого источника прерывания имеется бит разрешения, как в КВВП, так и в УВВ. У МК STM32 используется 16 уровней приоритетов.
Всего предусмотрено 16 регистров приоритета. Каждый из них разделен на четыре 8-битных поля для задания приоритета. Каждое поле связано с конкретным вектором прерывания. У МК STM32 используется только половина такого поля, т.к. реализовано только 16 уровней приоритета. Однако необходимо помнить, что активные биты приоритета находятся в старшей тетраде поля. По умолчанию поле приоритета определяет 16 уровней приоритета, причем уровень 0 - наивысший приоритет, а 15- низший. Поле приоритета также можно представить в виде групп и подгрупп приоритета. Это не добавляет дополнительных уровней приоритета, просто облегчает управление ими при необходимости задания в поле PRIGROUP регистра прикладных прерываний и управления сбросом большого числа прерываний.
Поле PRIGROUP разделяет уровни приоритетов на группы и подгруппы. Это необходимо для повышения программной абстракции при работе с большим числом прерываний
PRIGR | Положение | Группа | Подгруппа | |||
OUP (3 | запятой в | приоритета | приоритета | |||
бита) | двоичном числе | |||||
(группа.подгруппа) | ||||||
Кол-во бит | Кол-во | Кол-во бит | Кол-во | |||
уровн | уровн | |||||
ей | ей | |||||
011 | 4.0 | гггг | 4 | 16 | 0 | 0 |
100 | 3.1 | гггп | 3 | 8 | 1 | 2 |
101 | 2.2 | ггпп | 2 | 4 | 2 | 4 |
110 | 1.3 | гппп | 1 | 2 | 3 | 8 |
111 | 0.4 | пппп | 0 | 0 | 4 | 16 |
Трехбитное поле PRIGROUP управляет разделением 4-битных полей приоритета на группы и подгруппы. Например, запись в PRIGROUP числа 3 приведет к созданию двух групп с 4 уровнями приоритетов в каждой. После этого, вы можете в программе выполнить определения высокоприоритетной и низкоприоритетной групп прерываний. В рамках каждой группы можно задавать подуровни, в т.ч. низкий, средний, высокий и очень высокий. Ранее уже говорилось, что это позволяет более абстрактно смотреть на структуру прерываний и помогает программисту управлять большим числом прерываний. Конфигурация прерываний УВВ очень похожа на конфигурацию внутренних исключительных ситуаций процессора Cortex. Если взять в качестве примера прерывание АЦП, то вначале необходимо установить вектор прерывания и создать процедуру обработки прерываний:
DCD ADC_IRQHandler ;
void ADC_Handler void { }
Затем необходимо инициализировать АЦП и разрешить прерывание в регистрах УВВ и КВВП:
ADC1->CR2 = ADC_CR2; //Включение АЦП в режиме непрерывных преобразований
ADC1->SQR1 = sequence1; //Выбор номеров каналов в очереди преобразования
ADC1->SQR2 = sequence2; //и выбор каналов для преобразования
ADC1->SQR3 = sequence3;
ADC1->CR2 |= ADC_CR2; //Перезапись бита включения
ADC1->CR1 = ADC_CR1; //Запуск группы каналов, разрешение прерывания АЦП
GPIOB->CRH = 0x33333333; //Настройка светодиодных выводов на выход
NVIC->Enable[0] = 0x00040000; //Разрешение прерывания АЦП
[a1]
Дата добавления: 2020-01-07; просмотров: 377; Мы поможем в написании вашей работы! |
Мы поможем в написании ваших работ!