OSDev Wiki
Advertisement

Общие сведения

Контроллер прерываний NVIC является неотъемлемой частью процессоров M-профиля архитектуры ARM. В зависимости от особенностей конкретной реализации он может поддерживать до 496 линий запросов прерываний в версиях архитектуры ARMv7-M и ARMv8-M и до 32 линий в версии ARMv6-M. Для ARMv7-M и ARMv8-M количество линий запросов прерываний можно определить, прочитав содержимое формально не относящегося к NVIC регистра ICTR; для версии ARMv6-M возможности программно определить количество линий нет.

Если какие-либо линии прерываний не реализованы, соответствующие им биты и поля регистров NVIC являются зарезервированными: при считывании они содержат нули, а запись в них игнорируется. Заметим, что архитектура допускает «разрывы» между группами линий запросов прерываний, поэтому неполными (содержащими зарезервированные поля) могут быть любые регистры, а не только последний в каждой группе регистров.

Функционирование контроллера прерываний

Фиксация запросов прерываний

Запросы прерываний поступают в NVIC по нескольким линиям, число которых определяется реализацией. Согласно документации фирмы ARM, каждая из этих линий может обнаруживать запросы по уровню сигнала (level-sensitive) или по импульсу (pulse-sensitive), что, однако, контролируется не программистом, а определяется во время создания микросхемы микроконтроллера в зависимости от потребностей устройств, подключаемых к тем или иным линиям запроса прерываний.

Методы обнаружения запросов, используемые в NVIC, отличаются от таковых в подавляющем большинстве других контроллеров прерываний, используемых как с процессорами архитектуры ARM, так и в других архитектурах. Обнаружение по импульсу в определённой степени можно считать аналогом широко распространённого обнаружения запроса по перепаду (edge-sensitive); обнаружение по уровню, хотя и совпадает по названию с самым популярным методом, используемым практически во всех контроллерах прерываний, работает несколько иным способом. Ниже описывается логика функционирования NVIC в части, касающейся фиксации поступления запросов прерываний, как она видится в соответствии с приводимым в документации псевдокодом.

1. Запрос на перевод некоторого прерывания в состояние «ожидает обработки» (pending) возникает при выполнении любого из следующих трёх условий:

  • при записи 1 в соответствующий бит одного из регистров ISPR (программная установка запроса внешнего прерывания). Хотя в приводимом в документации псевдокоде это не указано прямо, резонно предположить, что сюда относится и программная выдача запроса прерывания с помощью записи в регистр STIR (об чём имеется упоминание в описании);
  • при наличии на линии запроса прерывания активного уровня, в то время как данное прерывание не является активным (active), т. е. соответствующий ему обработчик ещё не вызван. В частности, при наличии активного уровня на линии запроса прерывания последнее перейдёт в состояние «ожидает обработки» в момент сброса признака активности этого прерывания, что происходит при выходе из ранее вызванного обработчика данного прерывания либо при записи 1 в бит AIRCR.VECTCLRACTIVE;
  • при переходе линии запроса прерывания из неактивного в активное состояние, когда данное прерывание уже является активным. Таким образом, исчезновение и повторная выдача запроса прерывания при активном обработчике прерывания приведёт к тому, что это прерывание вновь станет ожидающим обработки, что повлечёт за собой повторный вызов обработчика, когда это станет возможным.

Заметим, что, согласно имеющимся исходным кодам ядер Cortex-M1 и Cortex-M3, переход из неактивного в активное состояние обнаруживается сравнением уровней на линии запроса прерывания в моменты прохождения фронта глобального тактового импульса, чем NVIC отличается от многих других контроллеров прерываний, которые фиксируют появление запроса по самому факту изменения состояния на линии запроса без учёта каких-либо тактовых импульсов. В то же время документация на ARMv8-M прямо говорит о том, чтов в некоторых реализациях сигнал запроса прерывания должен удерживаться активным достаточно долго, чтобы быть надёжно зарегистрированным; этим определением, по сути, разрешается реализация фиксации запроса прерывания как по фронту синхросигнала (для чего сигнал запроса должен удерживаться достаточное время – превышающее период следования синхросигналов), так и по фронту собственно сигнала запроса прерывания (и тогда сигнал запроса может быть намного короче).

2. Запрос на сброс состояния «ожидает обработки» возникает при выполнении любого из следующих двух условий:

  • при вызове обработчика данного прерывания (переход прерывания из состояния «ожидает обработки» в состояние «активно»);
  • при записи 1 в соответствующий разряд регистра ICPR при условии, что на линии запроса прерывания в это время находится неактивный уровень.

Таким образом, запрос прерывания уровнем, используемый в NVIC, отличается от классического запроса уровнем тем, что состояние «ожидает обработки» сбрасывается при вызове обработчика данного прерывания, в то время как при классическом запросе уровнем оно бы сохранялось до тех пор, пока линия запроса прерывания не перешла бы в неактивное состояние (что происходит при снятии запроса прерывания самим устройством, выдавшим запрос; по сути, классический контроллер прерывания не хранит в каком-то своём триггере состояние «ожидает обработки», а определяет его по текущему состоянию линии запроса). Запрос прерывания импульсом отличается от запроса прерывания фронтом тем, что состояние «ожидает обработки» в зависимости от реализации может фиксироваться в том случае, если переход линии запроса прерывания из неактивного в активное состояние имел место между двумя импульсами синхронизации, причём в активном состоянии запрос находился достаточно долго, чтобы этот переход был зафиксирован по очередному фронту синхросигнала (классический запрос фронтом является асинхронным: прерывание становится ожидающим обработки сразу при переходе линии запроса из неактивного состояния в активное независимо от каких-либо синхросигналов).

Заметим, что возможность программной установки или сброса состояния «ожидает обработки» для той или иной линии запроса прерывания определяется реализацией.

Управление прерываниями

Каждая линия запроса прерывания может быть индивидуально разрешена или запрещена. Если некоторое прерывание запрещено, появление соответствующего запроса будет зафиксировано (прерывание перейдёт в состояние «ожидает обработки»), однако не приведёт к собственно прерыванию (переход его в состояние «активно» невозможен). В конкретной аппаратной реализации некоторые запросы прерываний могут быть принудительно разрешены (попытка их запретить игнорируется), а другие — принудительно запрещены (это имеет место в отношении линий, которые логически имеются, но физически не реализованы или не используются).

Каждому запросу прерывания программа может назначить собственный приоритет.

Для каждого запроса потенциально возможна программная установка или сброс состояния ожидания обработки, однако реальная поддержка этой возможности для той или иной линии зависит от реализации. Помимо возможности сброса или установки бита состояния ожидания через соответствующие регистры NVIC, имеется возможность программной выдачи запроса внешнего прерывания с помощью регистра STIR, формально не входящего в состав NVIC.

В архитектурах ARMv7-M и ARMv8-M программа может прочитать биты активности каждого из возможных запросов прерываний и тем самым определить, какие прерывания обрабатываются в данный момент. В процессорах архитектуры ARMv6-M такой возможности нет.

Если процессор имеет расширение безопасности, одни прерывания могут адресоваться безопасному режиму, а другие – небезопасному. Код небезопасного режима не может повлиять на обработку прерываний безопасного режима или проверить состояние их активности.

Регистры контроллера прерываний

Список регистров, входящих в состав NVIC, приведён в следующей таблице. В управлении прерываниями, помимо этих регистров, участвует ряд регистров состояния процессора и регистров пространства управления системой.

Адрес Обозначение Доступ Значение после сброса Описание
E000E100-E000E13C NVIC_ISER0 – NVIC_ISER15
RW
00000000
Регистры разрешения прерываний
E000E180-E000E1BC NVIC_ICER0 – NVIC_ICER15
RW
00000000
Регистры запрещения прерываний
E000E200-E000E23C NVIC_ISPR0 – NVIC_ISPR15
RW
00000000
Регистры установки состояния «ожидает обработки»
E000E280-E000E2BC NVIC_ICPR0 – NVIC_ICPR15
RW
00000000
Регистры сброса состояния «ожидает обработки»
E000E300-E000E33C NVIC_IABR0 – NVIC_IABR15
RO
00000000
Регистры активности прерываний
E000E380-E000E3BC NVIC_ITNS0 – NVIC_ITNS15
RO
00000000
Регистры небезопасных прерываний
E000E400-E000E5EC NVIC_IPR0 – NVIC_IPR123
RW
00000000
Регистры приоритетов прерываний

Все регистры, кроме NVIC_IPR, доступны лишь как полные слова. В версиях ARMv8-M с основным расширением и ARMv7-M регистры NVIC_IPR могут адресоваться полными словами, полусловами или отдельными байтами; в версиях ARMv8-M без основного расширения и ARMv6-M они должны адресоваться лишь полными словами. Попытка выполнить иной доступ приведёт к непредсказуемым последствиям. Регистры NVIC_ITNS фактически имеются лишь при наличии расширения безопасности (формально они всегда присутствуют в любой реализации ARMv8-M и отсутствуют в более старых версиях).

Поля всех регистров, кроме NVIC_ITNS, доступны для небезопасных доступов лишь в том случае, если соответствующие прерывания обрабатываются в небезопасном режиме, в противном случае эти поля зарезервированы (считываются как нуль, запись игнорируется). Регистры NVIC_ITNS для небезопасных доступов зарезервированы всегда.

Количество реально имеющихся регистров зависит от числа реализованных линий запросов прерываний. Один регистр, за исключением NVIC_IPR, соответствует 32 линиям запросов прерываний, один регистр NVIC_IPR — четырём линиям. Биты, соответствующие нереализованным или неиспользуемым прерываниям, зарезервированы (считываются как нули, а запись в них игнорируется).

Примечание. В некоторых документах фирмы ARM относительно диапазона адресов, занимаемых регистрами приоритетов прерываний, допущена ошибка: указан диапазон от E000E400 до E000E7EC.

Регистры разрешения прерываний NVIC_ISER

Адрес: E000E100-E000E13C.
Доступ: только привилегированный, полным словом.
Наличие: NVIC_ISER0 присутствует всегда; общее число регистров зависит от количества реализованных линий запросов прерываний.
Безопасность: имеется одна версия регистров независимо от поддержки расширения безопасности. Безопасный код может обращаться к регистрам как по основным адресам в диапазоне E000E100-E000E13C, так и по их зеркалам в диапазоне E002E100-E002E13C; для отладчика и небезопасного кода диапазон E002E100-E002E13C зарезервирован. Поля, соответствующие прерываниям, обрабатываемым в безопасном режиме, для небезопасных доступов являются зарезервированными.

Формат регистра разрешения прерываний NVIC_ISER

Разряды Доступ Обозначение Функция
31:0
RW
SETENA Каждый разряд соответствует одной линии запроса прерываний: бит 0 — линии с номером 32*N, бит 1 — линии с номером 32*N+1 и т.д., где N — номер данного регистра.

При записи:

  • 0 — игнорируется
  • 1 — прерывание разрешается

При считывании:

  • 0 — прерывание запрещено
  • 1 — прерывание разрешено

Регистры запрещения прерываний NVIC_ICER

Адрес: E000E180-E000E1BC.
Доступ: только привилегированный, полным словом.
Наличие: NVIC_ICER0 присутствует всегда; общее число регистров зависит от количества реализованных линий запросов прерываний.
Безопасность: имеется одна версия регистров независимо от поддержки расширения безопасности. Безопасный код может обращаться к регистрам как по основным адресам в диапазоне E000E180-E000E1BC, так и по их зеркалам в диапазоне E002E180-E002E1BC; для отладчика и небезопасного кода диапазон E002E180-E002E1BC зарезервирован. Поля, соответствующие прерываниям, обрабатываемым в безопасном режиме, для небезопасных доступов являются зарезервированными.

Формат регистра запрещения прерываний NVIC_ICER

Разряды Доступ Обозначение Функция
31:0
RW
CLRENA Каждый разряд соответствует одной линии запроса прерываний: бит 0 — линии с номером 32*N, бит 1 — линии с номером 32*N+1 и т.д., где N — номер данного регистра.

При записи:

  • 0 — игнорируется
  • 1 — прерывание запрещается

При считывании:

  • 0 — прерывание запрещено
  • 1 — прерывание разрешено

Регистры установки состояния «ожидает обработки» NVIC_ISPR

Адрес: E000E200-E000E23C.
Доступ: только привилегированный, полным словом.
Наличие: NVIC_ISPR0 присутствует всегда; общее число регистров зависит от количества реализованных линий запросов прерываний.
Безопасность: имеется одна версия регистров независимо от поддержки расширения безопасности. Безопасный код может обращаться к регистрам как по основным адресам в диапазоне E000E200-E000E23C, так и по их зеркалам в диапазоне E002E200-E002E23C; для отладчика и небезопасного кода диапазон E002E200-E002E23C зарезервирован. Поля, соответствующие прерываниям, обрабатываемым в безопасном режиме, для небезопасных доступов являются зарезервированными.

Формат регистра установки состояния ожидания обработки прерываний NVIC_ISPR

Разряды Доступ Обозначение Функция
31:0
RW
SETPEND Каждый разряд соответствует одной линии запроса прерываний: бит 0 — линии с номером 32*N, бит 1 — линии с номером 32*N+1 и т.д., где N — номер данного регистра.

При записи:

  • 0 — игнорируется
  • 1 — состояние ожидания обработки устанавливается

При считывании:

  • 0 — прерывание не находится в состоянии ожидания обработки
  • 1 — прерывание находится в состоянии ожидания обработки

Регистры сброса состояния «ожидает обработки» NVIC_ICPR

Адрес: E000E280-E000E2BC.
Доступ: только привилегированный, полным словом.
Наличие: NVIC_ICPR0 присутствует всегда; общее число регистров зависит от количества реализованных линий запросов прерываний.
Безопасность: имеется одна версия регистров независимо от поддержки расширения безопасности. Безопасный код может обращаться к регистрам как по основным адресам в диапазоне E000E280-E000E2BC, так и по их зеркалам в диапазоне E002E280-E002E2BC; для отладчика и небезопасного кода диапазон E002E280-E002E2BC зарезервирован. Поля, соответствующие прерываниям, обрабатываемым в безопасном режиме, для небезопасных доступов являются зарезервированными.

Формат регистра сброса состояния ожидания обработки прерываний NVIC_ICPR

Разряды Доступ Обозначение Функция
31:0
RW
CLRPEND Каждый разряд соответствует одной линии запроса прерываний: бит 0 — линии с номером 32*N, бит 1 — линии с номером 32*N+1 и т.д., где N — номер данного регистра.

При записи:

  • 0 — игнорируется
  • 1 — состояние ожидания обработки сбрасывается (если нет нового запроса этого же прерывания; в таком случае состояние ожидания сбросить невозможно)

При считывании:

  • 0 — прерывание не находится в состоянии ожидания обработки
  • 1 — прерывание находится в состоянии ожидания обработки

Регистры активности прерываний NVIC_IABR

Адрес: E000E300-E000E33C.
Доступ: только привилегированный, полным словом.
Наличие: в ARMv6-M отсутствуют; в последующих версиях NVIC_IABR0 присутствует всегда, а общее число регистров зависит от количества реализованных линий запросов прерываний.
Безопасность: имеется одна версия регистров независимо от поддержки расширения безопасности. Безопасный код может обращаться к регистрам как по основным адресам в диапазоне E000E300-E000E33C, так и по их зеркалам в диапазоне E002E300-E002E33C; для отладчика и небезопасного кода диапазон E002E300-E002E33C зарезервирован. Поля, соответствующие прерываниям, обрабатываемым в безопасном режиме, для небезопасных доступов являются зарезервированными.

Формат регистра активности прерываний NVIC_IABR

Разряды Доступ Обозначение Функция
31:0
RW
ACTIVE Каждый разряд соответствует одной линии запроса прерываний: бит 0 — линии с номером 32*N, бит 1 — линии с номером 32*N+1 и т.д., где N — номер данного регистра:
  • 0 — прерывание не активно
  • 1 — прерывание активно

Регистры небезопасных прерываний NVIC_ITNS

Адрес: E000E380-E000E3BC.
Доступ: только привилегированный, полным словом.
Начиная с ARMv8.1-M, в зависимости от реализации запись отладчика в эти регистры может игнорироваться, если процессор не остановлен.
Наличие: в ARMv6-M и ARMv7-M отсутствуют; в ARMv8-M формально NVIC_ITNS0 присутствует всегда, а общее число регистров зависит от количества реализованных линий запросов прерываний. Реально, если расширение безопасности отсутствует, эти регистры отсутстуют и в ARMv8-M, поскольку в такой ситуации их значение всегда равно нулю и не может быть изменено.
Безопасность: имеется одна версия регистров независимо от поддержки расширения безопасности, однако при небезопасном обращении к регистрам доступ игнорируется.

Формат регистра небезопасных прерываний NVIC_ITNS

Разряды Доступ Обозначение Функция
31:0
RW
ITMS Каждый разряд соответствует одной линии запроса прерываний: бит 0 — линии с номером 32*N, бит 1 — линии с номером 32*N+1 и т.д., где N — номер данного регистра:
  • 0 — данное прерывание обрабатывается в безопасном состоянии
  • 1 — данное прерывание обрабатывается в небезопасном состоянии

Если некоторый бит сброшен, т. е. прерывание адресуется безопасному режиму, поля других регистров, соответствующие данному прерыванию, при небезопасном доступе считаются зарезервированными (считываются как нули, а запись игнорируется).

Биты, соответствующие нереализованным линиям запросов прерываний, являются зарезервированными. В зависимости от реализации определённые разряды, соответствующие реализованным линиям, могут быть жёстко установлены в 1, принудительно задавая обработку соответствующих прерываний только в безопасном состоянии

Регистры приоритетов прерываний NVIC_IPR

Адрес: E000E400-E000E5EC
Доступ: только привилегированный. В ARMv8-M с основным расширением и в ARMv7-M возможен доступ полными словами, полусловами или отдельными байтами; в ARMv8-M без основного расширения и в ARMv6-M – только полными словами.
Начиная с ARMv8.1-M, в зависимости от реализации запись отладчика в эти регистры может игнорироваться, если процессор не остановлен.
Наличие: NVIC_IPR0 присутствует всегда, а общее число регистров зависит от количества реализованных линий запросов прерываний.
Безопасность: имеется одна версия регистров независимо от поддержки расширения безопасности. Безопасный код может обращаться к регистрам как по основным адресам в диапазоне E000E300-E000E33C, так и по их зеркалам в диапазоне E002E300-E002E33C; для отладчика и небезопасного кода диапазон E002E300-E002E33C зарезервирован. Поля, соответствующие прерываниям, обрабатываемым в безопасном режиме, для небезопасных доступов являются зарезервированными.

Формат регистра приоритетов прерываний NVIC_IPR

Разряды Доступ Обозначение Функция
31:24
RW
PRI_N3 Приоритет прерывания с номером 4*N+3, где N — номер данного регистра
23:16
RW
PRI_N2 Приоритет прерывания с номером 4*N+2, где N — номер данного регистра
15:8
RW
PRI_N3 Приоритет прерывания с номером 4*N+1, где N — номер данного регистра
7:0
RW
PRI_N3 Приоритет прерывания с номером 4*N, где N — номер данного регистра

Количество реально имеющихся битов приоритета зависит от реализации (например, для версии ARMv6-M их всегда только два). Реализованные биты всегда являются старшими разрядами поля приоритета, при этом младшие биты считываются как нули, а запись в них игнорируется.

Advertisement