2.4.5.3. Конфигурация и использование КВВП
Чтобы включить в работу КВВП необходимо выполнить три действия. Вначале сконфигурировать таблицу векторов используемых прерываний. Затем настроить регистры КВВП с целью активизации и установки уровней приоритета прерываний КВВП. И, наконец, настроить УВВ и разрешить поддержку ими прерываний.
2.4.5.3.1. Таблица векторов исключительных ситуаций
Таблица векторов 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)
{
}
|
Теперь, когда сконфигурирована таблица векторов и объявлена процедура обработки прерываний, мы можем настроить КВВП на обработку прерывания таймера SysTick. Обычно, для этого выполняют две операции: задается приоритет прерывания, а затем разрешается источник прерывания. Регистры КВВП расположены в области системных ресурсов.
Регистры КВВП находятся в области системных ресурсов 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 разделяет уровни приоритетов на группы и подгруппы. Это необходимо для повышения программной абстракции при работе с большим числом прерываний
PRIGROUP (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; //Разрешение прерывания АЦП
NVIC->Enable[1] = 0x00000000;
|
|