Общие сведения
Контроллер прерываний 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 | Регистры разрешения прерываний | ||
E000E180-E000E1BC | NVIC_ICER0 – NVIC_ICER15 | Регистры запрещения прерываний | ||
E000E200-E000E23C | NVIC_ISPR0 – NVIC_ISPR15 | Регистры установки состояния «ожидает обработки» | ||
E000E280-E000E2BC | NVIC_ICPR0 – NVIC_ICPR15 | Регистры сброса состояния «ожидает обработки» | ||
E000E300-E000E33C | NVIC_IABR0 – NVIC_IABR15 | Регистры активности прерываний | ||
E000E380-E000E3BC | NVIC_ITNS0 – NVIC_ITNS15 | Регистры небезопасных прерываний | ||
E000E400-E000E5EC | NVIC_IPR0 – NVIC_IPR123 | Регистры приоритетов прерываний |
Все регистры, кроме 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 зарезервирован. Поля, соответствующие прерываниям, обрабатываемым в безопасном режиме, для небезопасных доступов являются зарезервированными.
Разряды | Доступ | Обозначение | Функция |
---|---|---|---|
SETENA | Каждый разряд соответствует одной линии запроса прерываний: бит 0 — линии с номером 32*N, бит 1 — линии с номером 32*N+1 и т.д., где N — номер данного регистра.
При записи:
При считывании:
|
Регистры запрещения прерываний NVIC_ICER
Адрес: E000E180-E000E1BC.
Доступ: только привилегированный, полным словом.
Наличие: NVIC_ICER0 присутствует всегда; общее число регистров зависит от количества реализованных линий запросов прерываний.
Безопасность: имеется одна версия регистров независимо от поддержки расширения безопасности. Безопасный код может обращаться к регистрам как по основным адресам в диапазоне E000E180-E000E1BC, так и по их зеркалам в диапазоне E002E180-E002E1BC; для отладчика и небезопасного кода диапазон E002E180-E002E1BC зарезервирован. Поля, соответствующие прерываниям, обрабатываемым в безопасном режиме, для небезопасных доступов являются зарезервированными.
Разряды | Доступ | Обозначение | Функция |
---|---|---|---|
CLRENA | Каждый разряд соответствует одной линии запроса прерываний: бит 0 — линии с номером 32*N, бит 1 — линии с номером 32*N+1 и т.д., где N — номер данного регистра.
При записи:
При считывании:
|
Регистры установки состояния «ожидает обработки» NVIC_ISPR
Адрес: E000E200-E000E23C.
Доступ: только привилегированный, полным словом.
Наличие: NVIC_ISPR0 присутствует всегда; общее число регистров зависит от количества реализованных линий запросов прерываний.
Безопасность: имеется одна версия регистров независимо от поддержки расширения безопасности. Безопасный код может обращаться к регистрам как по основным адресам в диапазоне E000E200-E000E23C, так и по их зеркалам в диапазоне E002E200-E002E23C; для отладчика и небезопасного кода диапазон E002E200-E002E23C зарезервирован. Поля, соответствующие прерываниям, обрабатываемым в безопасном режиме, для небезопасных доступов являются зарезервированными.
Разряды | Доступ | Обозначение | Функция |
---|---|---|---|
SETPEND | Каждый разряд соответствует одной линии запроса прерываний: бит 0 — линии с номером 32*N, бит 1 — линии с номером 32*N+1 и т.д., где N — номер данного регистра.
При записи:
При считывании:
|
Регистры сброса состояния «ожидает обработки» NVIC_ICPR
Адрес: E000E280-E000E2BC.
Доступ: только привилегированный, полным словом.
Наличие: NVIC_ICPR0 присутствует всегда; общее число регистров зависит от количества реализованных линий запросов прерываний.
Безопасность: имеется одна версия регистров независимо от поддержки расширения безопасности. Безопасный код может обращаться к регистрам как по основным адресам в диапазоне E000E280-E000E2BC, так и по их зеркалам в диапазоне E002E280-E002E2BC; для отладчика и небезопасного кода диапазон E002E280-E002E2BC зарезервирован. Поля, соответствующие прерываниям, обрабатываемым в безопасном режиме, для небезопасных доступов являются зарезервированными.
Разряды | Доступ | Обозначение | Функция |
---|---|---|---|
CLRPEND | Каждый разряд соответствует одной линии запроса прерываний: бит 0 — линии с номером 32*N, бит 1 — линии с номером 32*N+1 и т.д., где N — номер данного регистра.
При записи:
При считывании:
|
Регистры активности прерываний NVIC_IABR
Адрес: E000E300-E000E33C.
Доступ: только привилегированный, полным словом.
Наличие: в ARMv6-M отсутствуют; в последующих версиях NVIC_IABR0 присутствует всегда, а общее число регистров зависит от количества реализованных линий запросов прерываний.
Безопасность: имеется одна версия регистров независимо от поддержки расширения безопасности. Безопасный код может обращаться к регистрам как по основным адресам в диапазоне E000E300-E000E33C, так и по их зеркалам в диапазоне E002E300-E002E33C; для отладчика и небезопасного кода диапазон E002E300-E002E33C зарезервирован. Поля, соответствующие прерываниям, обрабатываемым в безопасном режиме, для небезопасных доступов являются зарезервированными.
Разряды | Доступ | Обозначение | Функция |
---|---|---|---|
ACTIVE | Каждый разряд соответствует одной линии запроса прерываний: бит 0 — линии с номером 32*N, бит 1 — линии с номером 32*N+1 и т.д., где N — номер данного регистра:
|
Регистры небезопасных прерываний NVIC_ITNS
Адрес: E000E380-E000E3BC.
Доступ: только привилегированный, полным словом.
Начиная с ARMv8.1-M, в зависимости от реализации запись отладчика в эти регистры может игнорироваться, если процессор не остановлен.
Наличие: в ARMv6-M и ARMv7-M отсутствуют; в ARMv8-M формально NVIC_ITNS0 присутствует всегда, а общее число регистров зависит от количества реализованных линий запросов прерываний. Реально, если расширение безопасности отсутствует, эти регистры отсутстуют и в ARMv8-M, поскольку в такой ситуации их значение всегда равно нулю и не может быть изменено.
Безопасность: имеется одна версия регистров независимо от поддержки расширения безопасности, однако при небезопасном обращении к регистрам доступ игнорируется.
Разряды | Доступ | Обозначение | Функция |
---|---|---|---|
ITMS | Каждый разряд соответствует одной линии запроса прерываний: бит 0 — линии с номером 32*N, бит 1 — линии с номером 32*N+1 и т.д., где N — номер данного регистра:
Если некоторый бит сброшен, т. е. прерывание адресуется безопасному режиму, поля других регистров, соответствующие данному прерыванию, при небезопасном доступе считаются зарезервированными (считываются как нули, а запись игнорируется). Биты, соответствующие нереализованным линиям запросов прерываний, являются зарезервированными. В зависимости от реализации определённые разряды, соответствующие реализованным линиям, могут быть жёстко установлены в 1, принудительно задавая обработку соответствующих прерываний только в безопасном состоянии |
Регистры приоритетов прерываний NVIC_IPR
Адрес: E000E400-E000E5EC
Доступ: только привилегированный. В ARMv8-M с основным расширением и в ARMv7-M возможен доступ полными словами, полусловами или отдельными байтами; в ARMv8-M без основного расширения и в ARMv6-M – только полными словами.
Начиная с ARMv8.1-M, в зависимости от реализации запись отладчика в эти регистры может игнорироваться, если процессор не остановлен.
Наличие: NVIC_IPR0 присутствует всегда, а общее число регистров зависит от количества реализованных линий запросов прерываний.
Безопасность: имеется одна версия регистров независимо от поддержки расширения безопасности. Безопасный код может обращаться к регистрам как по основным адресам в диапазоне E000E300-E000E33C, так и по их зеркалам в диапазоне E002E300-E002E33C; для отладчика и небезопасного кода диапазон E002E300-E002E33C зарезервирован. Поля, соответствующие прерываниям, обрабатываемым в безопасном режиме, для небезопасных доступов являются зарезервированными.
Разряды | Доступ | Обозначение | Функция |
---|---|---|---|
PRI_N3 | Приоритет прерывания с номером 4*N+3, где N — номер данного регистра | ||
PRI_N2 | Приоритет прерывания с номером 4*N+2, где N — номер данного регистра | ||
PRI_N3 | Приоритет прерывания с номером 4*N+1, где N — номер данного регистра | ||
PRI_N3 | Приоритет прерывания с номером 4*N, где N — номер данного регистра |
Количество реально имеющихся битов приоритета зависит от реализации (например, для версии ARMv6-M их всегда только два). Реализованные биты всегда являются старшими разрядами поля приоритета, при этом младшие биты считываются как нули, а запись в них игнорируется.