Advanced Interrupt Controller (AIC), встроенный в аппаратуру AT91SAM7X, это продвинутый векторный контроллер прерываний с поддержкой 8 уровней приоритетов, с возможностью индивидуально маскировать каждое из 32 обрабатываемых прерываний. Он разработан с целью кардинально уменьшить программную нагрузку на ядро процессора, чтобы снизить затраты процессорного времени на обработку внутренних и внешних прерываний.
AIC обрабатывает вход FIQ (fast interrupt request, быстрый запрос прерывания) и входы nIRQ (standard interrupt request, стандартный запрос прерывания) процессора ARM. Входы AIC это либо сигналы от внутренних периферийных устройств, либо внешние прерывания, поступающие в виде логических сигналов на выводы корпуса чипа процессора.
8-уровневый контроллер приоритетов AIC позволяет определить приоритет для каждого источника прерывания, разрешая тем самым осуществлять обработку в первую очередь прерывания с самым высоким приоритетом, даже если в данный момент активна обработка прерывания с менее высоким уровням.
Примечание: такая полезная возможность назначения приоритетов имеется далеко не у всех микроконтроллеров. Например, AVR RISC имеют фиксированную систему приоритетов, к тому же без специального разрешения прерываний внутри обработчика низкоуровневого прерывания оно не может быть прервано более приоритетным прерыванием. Подобную проблему с вытеснением низкоуровневых прерываний имеют даже очень дорогие процессоры, например DSP-процессоры Blackfin.
Внутренние источники прерывания могут быть запрограммированы на чувствительность к уровню логического сигнала (level sensitive), либо на чувствительность к его перепаду (edge triggered), т. е. к изменению уровня. Внешние источники прерывания можно запрограммировать на срабатывание от положительного перепада уровня (лог. 0 -> лог. 1), от отрицательного перепада уровня (лог. 1 -> лог. 0), либо на чувствительность к уровню лог. 0 или лог. 1.
Функция быстрого принудительного запуска прерывания (Fast Forcing) перенаправляет любой внутренний или внешний источник прерывания для предоставления быстрого прерывания вместо обычного прерывания.
Рис. 23-1. Упрощенная блок-схема AIC.
Обычные приложения (без операционный системы)
Приложения на основе операционной системы (обычно RTOS)
Драйверы операционной системы
Задачи жесткого реального времени
Обработчик прерываний операционной системы
Advanced Interrupt Controller (AIC)
Встроенные периферийные устройства
Внешние периферийные устройства
Рис. 23-2. Описание взаимодействия AIC с приложением.
Рис. 23-3. Подробная блок-схема AIC.
Таблица 23-1. Описание сигналов ввода/вывода.
Мнемоника
Описание вывода
Тип
FIQ
Fast Interrupt Query (запрос на быстрое прерывание)
Вход
IRQ0 .. IRQn
Прерывания 0 .. n
Вход
[Зависимости AIC]
Сигналы ввода/вывода (I/O). Сигналы прерывания FIQ и IRQ0 .. IRQn обычно мультиплексируются через контроллеры PIO [2]. В зависимости от возможностей контроллера PIO, используемого в конкретном типе процессора, выводы корпуса чипа должны быть запрограммированы в соответствии их назначенным функциям прерывания. Это правило не действует, когда PIO контроллер, используемый в процессоре, прозрачен для прохождения входного сигнала.
Управление питанием. AIC постоянно получает тактирование. Power Management Controller (PMC [3]) не оказывает никакого влияния на поведение AIC.
Установка выходов AIC, либо nIRQ, либо or nFIQ, приводит к пробуждению процессора ARM, если он находится в режиме приостановки/сна (режим пониженного энергопотребления, Idle Mode). Функция General Interrupt Mask позволяет AIC выводить из сна процессор без активации сигнала прерывания процессора, осуществляя тем самым синхронизацию процессоре по событию.
Источники прерывания. Interrupt Source 0 всегда назначен на FIQ. Если на корпусе процессора не реализован вывод FIQ, то Interrupt Source 0 не может использоваться.
Interrupt Source 1 всегда назначен на системное прерывание (System Interrupt). Это результат соединения функцией ИЛИ сигналов прерывания системных периферийных устройств, таких как System Timer, Real Time Clock (часы реального времени, RTC), Power Management Controller [3] и Memory Controller [4]. Когда происходит системное прерывание, его обработчик (interrupt service routine, ISR) должен сначала определить источник прерывания. Это осуществляется путем чтения регистров состояния вышеупомянутых системных периферийных устройств.
Источники прерывания 2 .. 31 могут быть либо подключены пользователем к выходам прерывания встроенных периферийных устройств, либо к сигналам внешних прерываний. Внешние сигналы прерывания могут быть подключены либо напрямую, либо через контроллер PIO.
PIO-контроллеры в контексте обработки прерываний рассматриваются как периферийные устройства. Соответственно сигналы прерывания контроллера PIO Controller подключаются к источникам прерывания 2 .. 31.
Идентификация периферийных устройств по соответствующему ему номеру прерывания определяется на уровне продукта (т. е. типа процессора), так же как номер бита, управляющий тактированием периферийного устройства. Соответственно для упрощения описания функциональных операций и интерфейса программирования источники прерывания именуются FIQ, SYS, PID2 .. PID31.
[Функциональное описание AIC]
Режим источника прерывания. AIC независимо программирует каждый источник прерывания. Поле SRCTYPE соответствующего AIC_SMR (Source Mode Register, регистр режима источника прерывания) выбирает условие прерывания для каждого источника.
Внутренние источники прерывания, подключенные на выходы прерываний встроенных периферийных устройств, можно запрограммировать либо в режиме чувствительности к уровню, (level-sensitive mode), либо в режиме срабатывания по перепаду уровня (edge-triggered mode). Активный уровень внутренних прерываний не имеет значения для пользователя.
Внешние источники прерываний можно запрограммировать либо в режиме чувствительности к уровню лог. 1 (high level-sensitive mode) или к уровню лог. 0 (low level-sensitive mode), или в режиме чувствительности либо к положительному, либо к отрицательному перепаду уровня.
Разрешение источника прерывания. Каждый источник прерывания, включая FIQ в источнике 0, можно разрешить или запретить с помощью регистров команд AIC_IECR (Interrupt Enable Command Register) и AIC_IDCR (Interrupt Disable Command Register). Этот набор регистров позволяет разрешать или запрещать прерывания в одной инструкции. Маска прерываний может быть прочитана в регистре AIC_IMR. Запрещенное прерывание не влияет на обработку других прерываний.
Очистка и установка прерываний. Все источники прерывания, запрограммированные на срабатывание по перепаду (включая FIQ на источнике 0) можно индивидуально установить или очистить записью в регистры AIC_ISCR и AIC_ICCR соответственно. Очистка или установка прерываний, запрограммированных на чувствительность у уровню, не оказывает никакого эффекта.
Операция очистки небрежная, поскольку программа должна выполнить действие для переинициализации схемы "запоминания", активированной при программирования источника прерывания в режиме срабатывания по перепаду (edge-triggered mode). Однако операция установки доступна для автотеста или в целях отладки. Она также может использоваться для реализации программных прерываний на основе AIC.
AIC автоматически очищает текущее прерывание, когда читается регистр AIC_IVR (Interrupt Vector Register). Эта операция осуществляется только для того источника прерывания, который AIC определил как текущее (см. далее описание контроллера приоритетов Priority Controller). Автоматическая очистка уменьшает количество операций, требуемых для ISR, так что коду ISR не нужно читать AIC_IVR. Имейте в виду, что автоматическая очистка прерывания запрещена, если на источнике прерывания разрешена функция Fast Forcing, так что считается, что это прерывание уникально работает как источник быстрого прерывания FIQ (подробнее см. далее описание "Fast Forcing").
Автоматическая очистка источника прерывания 0 выполняется при чтении AIC_FVR.
Статус прерывания. Для каждого прерывания результат работы AIC отражается в регистре AIC_IPR (Interrupt Pending Register, регистр ожидающих обработки прерываний), и это маскируется регистром AIC_IMR (Interrupt Mask Register). AIC_IPR разрешает реальную активность источников прерываний, независимо от того, замаскированы они или нет.
Чтение AIC_ISR дает номер текущего прерывания (см. далее "Priority Controller"), и регистр AIC_CISR дает образ сигналов nIRQ и nFIQ, присутствующих на процессоре.
Каждый из вышеупомянутых статусов может использоваться для оптимизации обработки прерываний в системе.
Рис. 23-4. Входной каскад внутренних источников прерываний (Internal Interrupt Source Input Stage).
Рис. 23-5. Входной каскад внешних источников прерываний (External Interrupt Source Input Stage).
Латентности прерывания. Под латентностью подразумевают задержку на реакцию, в данном контексте имеется в виду задержка между появлением события прерывания и запуском соответствующего прерыванию обработчика (Interrupt Service Routine, ISR). Глобальные латентности прерывания зависят от нескольких параметров, включая:
• Времени программного маскирования прерываний. • Произошло ли прерывание на уровне процессора, или на уровне AIC. • Времени выполнения инструкции, которая выполнялась в момент возникновения прерывания. • Влияние активности прерываний с более высоким уровнем приоритета и ресинхронизация аппаратных сигналов.
В этой секции рассматриваются только аппаратные ресинхронизации. Это дает подробную информацию по интервалам времени латентности между событием на внешнем прерывании и срабатывании прерывания (в режиме перепада или уровня), или активации внутреннего источника прерывания и соответствующей установки сигнала nIRQ или nFIQ на процессоре. Время ресинхронизации зависит от программирования источника прерывания и от его типа (внутренний или внешний). Для стандартного прерывания интервалы ресинхронизации даны в предположении, что в данный момент не выполняются обработчики прерываний с более высоким приоритетом.
Мультиплексирование PIO-контроллера [2] не влияет на латентности прерывания внешних источников прерывания.
Рис. 23-6. Внешнее прерывание в режиме срабатывания по перепаду (External Interrupt Edge Triggered Source).
Рис. 23-7. Внешнее прерывание в режиме срабатывания по уровню (External Interrupt Level Sensitive Source).
Рис. 23-8. Внутреннее прерывание в режиме срабатывания по перепаду (Internal Interrupt Edge Triggered Source).
Рис. 23-9. Внутреннее прерывание в режиме срабатывания по уровню (Internal Interrupt Level Sensitive Source).
[Стандартное прерывание]
Контроллер приоритетов (Priority Controller). 8-уровневый контроллер приоритетов управляет сигналами nIRQ на процессоре, в зависимости от событий прерывания на источниках 1 .. 31 (кроме тех, которые запрограммированы в Fast Forcing).
Каждый источник прерывания имеет программируемый уровень приоритета 7 .. 0, что определяет пользователь записью поля PRIOR в соответствующем регистре AIC_SMR (Source Mode Register). Уровень 7 соответствует самому высокому приоритету, и 0 самому низкому. Как только произошло событие прерывания, как это было определено полем SRCTYPE в AIC_SMR (Source Mode Register), устанавливается сигнал nIRQ. Новое событие прерывание может произойти на другом источнике прерывания, когда установился сигнал, в этой ситуации контроллер приоритетов определяет текущее прерывание в момент чтения AIC_IVR (Interrupt Vector Register). Чтение AIC_IVR является точкой входа в обработчик прерывания, что дает AIC возможность считать, что это прерывание учтено программой.
Текущий уровень приоритета определен как уровень приоритета текущего прерывания.
Если несколько прерываний с одинаковым приоритетом ожидают обработки и разрешены в момент чтения AIC_IVR, то сначала обрабатывается прерывание с самым низким номером источника прерывания.
Сигнал nIRQ может быть установлен только если событие прерывания произошло на источнике прерывания с более высоким приоритетом. Если произошло событие прерывания (или оно ожидает обработки) во время обработки прерывания, то его обработка откладывается, пока программа не покажет AIC окончание текущей обработки путем записи AIC_EOICR (End of Interrupt Command Register). Запись AIC_EOICR является точкой выхода из обработки прерывания.
Interrupt Nesting (вложенные прерывания). Контроллер приоритетов реализует вложенные вызовы прерываний, чтобы прерывание с более высоким приоритетом могло быть обработано на фоне активности менее приоритетных прерываний. Это требует, чтобы обработчики прерываний (ISR), у которых приоритет меньше, повторно разрешали прерывание на уровне процессора.
Когда произошло более приоритетное прерывание, и уже выполняется обработчик с приоритетом ниже, сигнал nIRQ выставляется заново. Если прерывание разрешено на уровне ядра, то текущее выполнение прерывается, и новый ISR должен прочитать AIC_IVR. В этот момент текущий номер прерывания и его уровень приоритета проталкивается во встроенный аппаратный стек, так что они сохраняются и восстанавливаются, когда более приоритетный ISR завершается, и записан AIC_EOICR.
AIC оборудован 8-уровневым аппаратным стеком для поддержки 8 вложений прерываний, так что можно поддерживать 8 уровней приоритета.
Векторизация прерываний. Адреса ISR, соответствующие каждому источнику прерывания, могут быть сохранены в регистрах AIC_SVR1 .. AIC_SVR31 (SVR означает Source Vector Register), номера у регистров векторов от 1 до 31. Когда процессор читает AIC_IVR (Interrupt Vector Register), то возвращается значение, записанное в AIC_SVR, соответствующее текущему прерыванию.
Примечание: векторизацией обычно называют назначение адресов для обработчиков прерываний (Interrupt Service Routine, сокращенно ISR). В этом описании под векторизацией также подразумевают аппаратную поддержку передачи управления на соответствующий ISR. Таким образом вектор это просто адрес обработчика ISR. Вектор исключений ARM это фиксированный адрес 0x00000018, куда передается управление при прерывании.
Регистры AIC_SVRx предоставляет способ ветвления в одной инструкции на ISR, соответствующий текущему прерыванию, так как AIC_IVR отображен на абсолютный адрес 0xFFFFF100, и таким образом доступен из вектора прерывания ARM по адресу 0x00000018 с помощью следующей инструкции:
LDRPC, [PC,# -&F20]
Когда процессор выполняет эту инструкцию, то он загружает значение, прочитанное из AIC_IVR, в свой программный счетчик, переходя таким способом на выполнение правильного ISR.
Эта возможность часто не используется, когда приложение основано на операционной системе (либо RTOS, либо не RTOS). Операционные системы часто имеют одну точку входа для всех прерываний, и первая выполняемая задача состоит в определении источника прерывания.
Однако при портировании операционной системы на процессоры AT91 настоятельно рекомендуется применять векторизацию прерываний. Это можно выполнить путем определения всех AIC_SVRx источника прерывания, чтобы они были обработаны операционной системой по адресу её обработчика прерывания. Если сделать так, то векторизация прерываний позволит критическому прерыванию передать выполнение на специальный очень быстрый ISR, не передавая управления на обычный ISR операционной системы. Это упрощает реализацию задач жесткого реального времени (ввод/вывод голосовых данных или звука, и программное обслуживание периферийных устройств), чтобы их выполнение было осуществлено эффективно и прозрачно для задач, выполняющихся под управлением операционной системы.
[ISR обычных прерываний]
Эта секция дает обзор последовательности быстрой обработки прерываний, когда используется AIC. Это описание подразумевает, что программист понимает архитектуру процессора ARM, особенно режимы прерываний процессора и связанных с этим бит статуса. Также это описание подразумевает следующее:
2. По адресу вектора исключений ARM 0x00000018 находится требуемая для векторизации прерываний инструкция
LDRPC, [PC,# -&F20]
Когда устанавливается сигнал nIRQ, если бит I регистра CPSR в лог. 0, то последовательность действий следующая:
1. CPSR сохраняется в SPSR_IRQ, текущее значение программного счетчика (PC) загружается в Interrupt link register (R14_irq) и программный счетчик (R15) загружается значением 0x18. В следующем цикле, во время выборки инструкции по адресу 0x1C, ядро ARM подстраивает значение R14_irq, декрементируя его на 4.
2. Ядро ARM переходит в режим прерывания, если оно еще в нем не находится.
3. Когда выполняется инструкция, загруженная по адресу 0x18, программный счетчик загружается значением, прочитанным в AIC_IVR. Чтение AIC_IVR дает следующее:
– Устанавливается текущее прерывание на ожидание, и разрешается выполнение прерывания с самым высоким приоритетом. Текущий уровень соответствует уровню приоритета текущего прерывания. – Снимается сигнал nIRQ на процессоре. Даже если векторизация не используется, AIC_IVR должен быть прочитан, чтобы снять сигнал nIRQ. – Прерывание автоматически очищается, если оно было запрограммировано на срабатывание по перепаду (edge-triggered). – В стек проталкивается текущий уровень и текущий номер прерывания. – Возвращается значение, записанное в AIC_SVR, соответствующее текущему прерыванию.
4. Предыдущий шаг дает эффект ветвления на ISR, соответствующий произошедшему прерыванию. Это должно начинаться путем сохранения link-регистра (R14_irq) и SPSR_IRQ. Link-регистр должен быть декрементирован на 4, когда он сохраняется, если он восстанавливается напрямую в программный счетчик при выходе из ISR. Для этого может использоваться, например, инструкция SUB PC, LR, #4.
5. Будущие прерывания могут быть затем демаскированы очисткой бита I в CPSR, позволяя тем самым ядру учитывать повторную установку сигнала nIRQ. Это может случиться, если произойдет прерывание с более высоким приоритетом, чем текущее.
6. После этого ISR может выполнить свои необходимые алгоритмические действия для обслуживания прерывания, с сохранением в стеке используемых регистров и восстановлением их из стека после завершения всех действий в конце ISR. Во время этой фазы 6 прерывание с более высоким приоритетом может повторить всю последовательность, начиная с шага 1.
Примечание: если прерывание запрограммировано на чувствительность к уровню (level sensitive), то во время фазы 6 источник прерывания должен быть очищен.
7. Бит I в CPSR должен быть установлен, для маскирования прерывания перед выходом, чтобы гарантировать прерывание будет выполнено в определенном порядке.
8. Регистр окончания прерывания (End of Interrupt Command Register, AIC_EOICR) должен быть записан, чтобы показать для AIC завершение текущего прерывания. Это приводит к выборке из стека текущего уровня, восстановлению предыдущего текущего уровня, если он имеется в стеке. Если ожидает обработки другое прерывание с меньшим приоритетом, чем старый текущий уровень, или с таким же приоритетом, но при наличии прерывания с более высоким уровнем, чем новый текущий уровень, то сигнал nIRQ устанавливается снова, но последовательность прерывания не будет запущено немедленно, потому что в ядре установлен бит I. Восстанавливается SPSR_IRQ. В завершение сохраненное значение link-регистра восстанавливается напрямую в PC. Это дает эффект возврата из прерывания к тому, что выполнялось прежде, и загрузки CPSR сохраненным SPSR, маскируя или демаскируя прерывания, в зависимости от состояния, сохраненного в SPSR_IRQ.
Примечание: бит I в SPSR очень важен. Если он установлен, то это показывает, что ядро ARM было на гране маскирования прерывания, когда инструкция маскирования была прервана. Следовательно, когда SPSR восстанавливается, инструкция маскирования завершается (прерывание маскируется).
[Быстрое прерывание (Fast Interrupt)]
Источник быстрого прерывания. Interrupt source 0 единственный источник, который может вызвать запрос быстрого прерывания для процессора, если не используется функция fast forcing. Interrupt source 0 обычно подключен к выводу FIQ корпуса процессора напрямую, либо через контроллер PIO [2].
Управление быстрым прерыванием. Логика Fast Interrupt в AIC не имеет контроллера прерываний. Режим interrupt source 0, запрограммированный AIC_SMR0 и полем PRIOR этого регистра, не используется, даже если будет прочитано то, что туда было записано. Поле SRCTYPE регистра AIC_SMR0 разрешает программировать источник fast interrupt на срабатывание по положительному или отрицательному перепаду, или запрограммировать источник fast interrupt для чувствительности к высокому или низкому уровню.
Запись 0x1 в AIC_IECR (Interrupt Enable Command Register) и AIC_IDCR (Interrupt Disable Command Register) соответственно разрешает и запрещает быстрое прерывание. Бит 0 регистра AIC_IMR (Interrupt Mask Register) показывает, разрешено или запрещено быстрое прерывание.
Векторизация Fast Interrupt. Адрес ISR для быстрого прерывания может быть сохранен в регистре AIC_SVR0 (Source Vector Register 0). Записанное в этот регистр значение возвращается, когда процессор читает AIC_FVR (Fast Vector Register). Это дает возможность ветвления на ISR в одной инструкции, так как AIC_FVR отображен на абсолютный адрес 0xFFFF F104, так что доступен из вектора быстрого прерывания ARM по адресу 0x0000001C следующей инструкцией:
LDRPC, [PC,# -&F20]
Когда процессор выполняет эту инструкцию, он загружает значение, прочитанное из AIC_FVR, в свой программный счетчик, выполняя тем самым переход на выполнение ISR быстрого прерывания. Это также выполняет автоматическую очистку источника быстрого прерывания, если он запрограммирован в режим срабатывания по перепаду (edge-triggered mode).
ISR быстрого прерывания. В этой секции дается обзор последовательности обработки быстрого прерывания, когда используется AIC. Это описание подразумевает, что программист понимает архитектуру процессора ARM, особенно режимы прерываний процессора и связанных с этим бит статуса. Также это описание подразумевает следующее:
2. По адресу быстрого вектора исключений ARM 0x0000001C (FIQ exception vector) находится требуемая для векторизации прерываний инструкция
LDRPC, [PC,# -&F20]
Когда устанавливается сигнал nFIQ, если бит F регистра CPSR в лог. 0, то последовательность действий следующая:
1. CPSR сохраняется в SPSR_FIQ, текущее значение программного счетчика сохраняется в FIQ link-регистре (R14_FIQ) и программный счетчик (R15) загружается значением 0x1C. На следующем такте, во время выборки по адресу 0x20, ядро ARM подстраивает R14_FIQ, декрементируя его на 4.
2. Ядро ARM входит в режим FIQ.
3. Когда выполняется инструкция, загруженная по адресу 0x1C, программный счетчик загружается значением, прочитанным из AIC_FVR. Чтение AIC_FVR дает эффект автоматической очистки быстрого прерывания, если оно было запрограммировано на срабатывание по перепаду (edge triggered). Только в этом случае на процессоре будет снят сигнал nFIQ.
4. Предыдущий шаг разрешает ветвление на соответствующий ISR. Нет необходимости сохранять link-регистр R14_FIQ и регистр SPSR_FIQ, если не требуется вложенность прерываний.
5. ISR может выполнять свои необходимые алгоритмические действия. Нет необходимости сохранять регистры R8 .. R13, потому что режим FIQ использует свои собственные выделенные регистры, и пользовательские регистры R8 .. R13 находятся в отдельном банке. Другие регистры R0 .. R7 должны перед использованием сохраняться и восстанавливаться в конце ISR (перед выполнением следующего шага 6). Обратите внимание, что если быстрое прерывание запрограммировано на чувствительность к уровню (level sensitive), то во время этой фазы источник прерывания должен быть очищен, чтобы снять сигнал interrupt source 0.
6. В завершение Link-регистр R14_FOQ восстанавливается в PC после декремента на 4 (например инструкцией SUB PC, LR, #4). Это дает эффект возврата из прерывания в тот код, который выполнялся ранее, загрузки CPSR значением SPSR и маскирования или демаскирования быстрого прерывания, в зависимости от значения, сохраненного в SPSR.
Примечание: бит F в SPSR имеет важное значение. Если он установлен, то это означает, что ядро ARM как раз собиралось маскировать прерывания FIQ, когда инструкция маскирования была прервана. Следовательно, когда SPSR восстановится, прерванная инструкция завершится (FIQ будет замаскировано).
Другой способ обработать быстрое прерывание - отобразить ISR на адрес ARM-вектора 0x1C. Этот метод не использует векторизацию, так что чтение AIC_FVR должно быть выполнено как можно ближе к началу ISR. Однако этот метод экономит время процессора, которое было бы потрачено на инструкции ветвления при использовании векторизации.
Fast Forcing. Функция Fast Forcing AIC позволяет перенаправлять любой обычный источник прерывания на контроллер быстрого прерывания.
Fast Forcing разрешается или запрещается записью Fast Forcing Enable Register (AIC_FFER) и Fast Forcing Disable Register (AIC_FFDR) соответственно. Запись в эти регистры приводит к обновлению Fast Forcing Status Register (AIC_FFSR), который управляет этой функцией для каждого внутреннего или внешнего источника прерывания.
Когда Fast Forcing разрешено, источники прерывания обрабатываются так, как это было описано ранее.
При разрешенном Fast Forcing программирование чувствительности edge/level и, в некоторых случаях, детектирование перепада источника прерывания все еще активно, однако источник не может вызвать обычное прерывание для процессора, и его не видит система обработки приоритета.
Если источник прерывания запрограммирован в режим level-sensitive, и был захвачен активный уровень, то Fast Forcing приведет к установке для ядра сигнала nFIQ.
Если источник прерывания запрограммирован в режим edge-triggered, и был детектирован активный перепад, то Fast Forcing приведет к установке для ядра сигнала nFIQ.
Функция Fast Forcing не влияет на бит ожидания обработки Interrupt Source 0 pending в регистре отложенных прерываний (Interrupt Pending Register, AIC_IPR).
Регистр вектора быстрого прерывания (FIQ Vector Register, AIC_FVR) читает содержимое Source Vector Register 0 (AIC_SVR0), независимо от того, какой мог быть источник быстрого прерывания. Чтение FVR не очищает Interrupt Source 0, когда функция Fast Forcing используется, и источник прерывания должен быть очищен записью в Interrupt Clear Command Register (AIC_ICCR).
Все разрешенные и ожидающие обработки источники прерывания, у которых разрешена функция Fast Forcing, и которые запрограммированы в режим срабатывания по перепаду (edge-triggered mode), должны быть очищены запись в Interrupt Clear Command Register. При этом они очищаются независимо, в результате предотвращается потери прерываний.
Чтение AIC_IVR не очищает источник прерывания, у которого разрешена функция Fast Forcing.
Источник прерывания 0, зарезервированный для быстрого прерывания, продолжает нормальную работу и становится одним из источников быстрого прерывания.
Рис. 23-10. Функция Fast Forcing.
[Режим защиты]
Режим защиты (Protect Mode) позволяет читать регистр вектора прерывания (Interrupt Vector Register) без выполнения связанных с этим автоматических операций. Это необходимо, когда осуществляется отладка системы. Когда отладчик, работая либо с Debug Monitor, либо с ICE процессора ARM, останавливает приложения и обновляет открытые окна, он может читать регистры AIC и таким образом IVR. У этого есть нежелательные последствия:
• Если ожидает обработки разрешенное прерывание с более высоким приоритетом, чем текущее, то оно наслаивается (не знаю как перевести stacked). • Если нет разрешенных ожидающих обработки прерываний, будет возвращен spurious-вектор.
В любом случае, необходима команда End of Interrupt, чтобы подтвердить и восстановить контекст AIC. Эта операция обычно не выполняется системой отладки, так как что отлаживаемая система оказывается очень сильно подвержена разрушению, что переводит приложение в нежелательное состояние.
Этого избегают использованием Protect Mode. Запись поля DBGM в AIC_DCR (Debug Control Register) в значение 0x1 разрешает Protect Mode.
Когда разрешен Protect Mode, AIC выполняет наслоение прерываний только когда на AIC_IVR выполняется операция записи. Таким образом, подпрограммы ISR должны записать (произвольные данные) в AIC_IVR сразу после его чтения. С текущим прерыванием обновляется новый контекст AIC, включая значение Interrupt Status Register (AIC_ISR), только когда записывается AIC_IVR.
Самостоятельное чтение AIC_IVR (например отладчиком), не изменяет ни контекста AIC, ни AIC_ISR. Дополнительные чтения AIC_IVR выполняются теми же операциями. Однако рекомендуется не останавливать процессор между чтением и записью AIC_IVR в ISR, что гарантирует, что отладчик не модифицирует контекст AIC.
Давайте обобщим. В нормальном рабочем режиме чтение AIC_IVR выполняет в AIC следующие операции:
1. Вычисляет активное прерывание (с более высоким приоритетом, чем текущее, или spurious-прерывание). 2. Определяет и возвращает вектор активного прерывания. 3. Запоминает прерывание. 4. Проталкивает текущий уровень прерывания во внутренний стек. 5. Подтверждает прерывание.
Однако если активирован Protect Mode, выполняются только операции 1 .. 3, когда читается AIC_IVR. Операции 4 и 5 выполняются AIC, только когда записывается AIC_IVR.
Программа, которая написана и отлажена в Protect Mode, будет без модификации нормально работать и в Normal Mode. Однако в Normal Mode запись AIC_IVR не оказывает эффекта, и может быть удалена с целью оптимизации кода.
[Ошибочное прерывание]
В AIC есть функция защиты от spurious (ошибочных) прерываний. Spurious-прерывание определено как достаточно долгая установка источника прерывания для AIC, чтобы установить сигнал nIRQ, но недостаточно долгая, чтобы существовать в момент чтения AIC_IVR. Это чаще всего случается в следующих условиях:
• Внешний источник прерывания запрограммирован в режим чувствительности к уровню (level-sensitive mode), и активный уровень присутствует только на короткое время. • Внутренний источник прерывания запрограммирован в режим чувствительности к уровню (level-sensitive mode), и выходной сигнал, соответствующий встроенному периферийному устройству, активируется на короткое время (что происходит в случае прерывания от Watchdog [5]). • Прерывание происходит всего лишь на несколько тактов раньше, чем программа начнет его маскировать, что в результате генерирует импульс на источнике прерывания.
AIC детектирует spurious-прерывание в момент, когда читается AIC_IVR, когда нет разрешенных, ожидающих обработки прерываний. Когда это происходит, AIC вернет значение, сохраненное программистом в AIC_SPU (Spurious Vector Register). Программист должен сохранить адрес обработчика spurious-прерывания в AIC_SPU как часть кода в приложении, чтобы как можно быстрее вернуться к нормальному выполнению приложения. Этот обработчик записывает в AIC_EOICR и выполняет возврат из прерывания.
[Общее маскирование прерываний]
В AIC есть бит общего запрета (маскирования) прерываний, General Interrupt Mask (бит GMSK в регистре AIC_DCR), который не дает прерываниям достигнуть процессора. Сигналы nIRQ и nFIQ переходят в неактивное состояние, если GMSK установлен. Однако эта маска не защищает от пробуждения процессора, если он вошел в режим сна (Idle Mode). Эта функция упрощает синхронизацию процессора со следующим событием, и как только событие произошло, будут выполнены соответствующие действия без обработки прерывания. Настоятельно рекомендуется с осторожностью использовать эту маску.
[Интерфейс пользователя AIC (регистры)]
Базовый адрес AIC отображен на адрес 0xFFFFF000, и занимает регистрами 4-килобайтное адресное пространство. Это позволяет реализовать функцию векторизации, так как инструкции load/store, работающие относительно PC, поддерживают только ± 4-килобайтное смещение.
Таблица 23-2. Отображение на память регистров AIC.
Смещение
Регистр
Мнемоника
Доступ(3)
Значение после сброса
0x0000
Source Mode Register 0
AIC_SMR0
RW
0x00000000
0x0004
Source Mode Register 1
AIC_SMR1
RW
0x00000000
...
...
...
...
...
0x007C
Source Mode Register 31
AIC_SMR31
RW
0x00000000
0x0080
Source Vector Register 0
AIC_SVR0
RW
0x00000000
0x0084
Source Vector Register 1
AIC_SVR1
RW
0x00000000
...
...
...
...
...
0x00FC
Source Vector Register 31
AIC_SVR31
RW
0x00000000
0x0100
Interrupt Vector Register
AIC_IVR
RO
0x00000000
0x0104
FIQ Interrupt Vector Register
AIC_FVR
RO
0x00000000
0x0108
Interrupt Status Register
AIC_ISR
RO
0x00000000
0x010C
Interrupt Pending Register(2)
AIC_IPR
RO
0x00000000(1)
0x0110
Interrupt Mask Register(2)
AIC_IMR
RO
0x00000000
0x0114
Core Interrupt Status Register
AIC_CISR
RO
0x00000000
0x0118
Зарезервировано
--
--
--
0x011C
--
--
--
0x0120
Interrupt Enable Command Register(2)
AIC_IECR
WO
--
0x0124
Interrupt Disable Command Register(2)
AIC_IDCR
WO
--
0x0128
Interrupt Clear Command Register(2)
AIC_ICCR
WO
--
0x012C
Interrupt Set Command Register(2)
AIC_ISCR
WO
--
0x0130
End of Interrupt Command Register
AIC_EOICR
WO
--
0x0134
Spurious Interrupt Vector Register
AIC_SPU
RW
0x00000000
0x0138
Debug Control Register
AIC_DCR
RW
0x00000000
0x013C
Зарезервировано
--
--
--
0x0140
Fast Forcing Enable Register(2)
AIC_FFER
WO
--
0x0144
Fast Forcing Disable Register(2)
AIC_FFDR
WO
--
0x0148
Fast Forcing Status Register(2)
AIC_FFSR
RO
0x00000000
Примечания:
(1) Значение сброса этого регистра зависит от уровня на внешнем источнике прерываний. Все другие источники очищаются сбросом, так что после сброса нет ожидания обработки их прерываний. (2) Битовые поля PID2..PID31 относятся к идентификаторам периферийных устройств, как это определено в секции "Peripheral Identifiers" даташита на процессор. (3) WO означает только запись (Write Only), RW означает чтение и запись (Read Write), RO означает только чтение (Read Only).
В микроконтроллерах AT91SAM7X (AT91SAM7512, AT91SAM7X256, AT91SAM7X128) встроено множество разной аппаратуры (периферийные устройства). Таблица 10-1 определяет идентификаторы периферийных устройств (Peripheral Identifiers) микроконтроллеров серии AT91SAM7X. Уникальные идентификаторы определены и для AIC (Advanced Interrupt Controller), и для PMC (Power Management Controller) [3].
Это регистры режима источника прерывания AIC_SMR0 .. AIC_SMR31.
31
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
-
-
-
-
-
-
-
-
-
SRCTYPE
-
-
PRIOR
PRIOR: Priority Level
Это поле программирует уровень приоритета для всех источников, кроме FIQ (source 0). Уровень приоритета может может быть от 0 (самый низкий приоритет) до 7 (самый высокий приоритет) включительно. Для FIQ не используется уровень приоритета в связанном SMR-регистре AIC_SMRx.
SRCTYPE: Interrupt Source Type
Активный уровень или перепад, по которому срабатывает прерывание. Этот параметр не программируется для внутренних источников прерывания.
SRCTYPE
Внутренние источники прерывания
Внешние источники прерывания
00
Чувствительность к лог. 1
Чувствительность к лог. 0
01
Срабатывание по положительному перепаду уровня (0 -> 1)
Срабатывание по отрицательному перепаду уровня (1 -> 0)
10
Чувствительность к лог. 1
Чувствительность к лог. 1
11
Срабатывание по положительному перепаду уровня
Срабатывание по положительному перепаду уровня
AIC Source Vector Register
Регистры AIC_SVR0 .. AIC_SVR31 используются для настройки адресов обработчиков прерывания.
31
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
VECTOR
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
VECTOR
VECTOR: Source Vector
Пользователь может сохранить в этих регистрах адреса соответствующего обработчика прерывания (ISR) для каждого источника прерывания.
AIC Interrupt Vector Register
Имя регистра AIC_IVR, он служит для чтения адреса текущего прерывания.
31
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
IRQV
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
IRQV
IRQV: Interrupt Vector Register
Interrupt Vector Register содержит вектор, запрограммированный пользователем в Source Vector Register, соответствующий текущему прерыванию. Source Vector Register индексируется с помощью номера текущего прерывания, когда программа читает Interrupt Vector Register.
Когда в настоящий момент нет текущего прерывания, из Interrupt Vector Register будет прочитано значение, сохраненное в AIC_SPU.
AIC FIQ Vector Register
Имя регистра AIC_FVR, он служит для чтения адреса текущего быстрого прерывания.
31
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
FIQV
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
FIQV
FIQV: FIQ Vector Register
FIQ Vector Register содержит вектор, запрограммированный пользователем в Source Vector Register 0. Когда в настоящее время нет быстрого прерывания, из FIQ Vector Register будет прочитано значение, сохраненное в AIC_SPU.
AIC Interrupt Status Register
Имя регистра AIC_ISR, он служит для чтения номера прерывания.
31
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
-
-
-
-
-
-
-
-
-
-
-
IRQID
IRQID: Current Interrupt Identifier
Чтение Interrupt Status Register вернет номер текущего источника прерывания.
AIC Interrupt Pending Register
Имя регистра AIC_IPR, он содержит флаги для определения прерываний, ожидающих обработки.
31
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
PID31
PID30
PID29
PID28
PID27
PID26
PID25
PID24
PID23
PID22
PID21
PID20
PID19
PID18
PID17
PID16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
PID15
PID14
PID13
PID12
PID11
PID10
PID9
PID8
PID7
PID6
PID5
PID4
PID3
PID2
SYS
FIQ
FIQ, SYS, PID2, .., PID31: Interrupt Pending
0 соответствует состоянию, когда нет ожидающего прерывания для соответствующего источника. 1 соответствует состоянию, когда для соответствующего источника имеется прерывание, ожидающее своей обработки.
AIC Interrupt Mask Register
Имя регистра AIC_IMR, он служит для маскирования источников прерывания.
31
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
PID31
PID30
PID29
PID28
PID27
PID26
PID25
PID24
PID23
PID22
PID21
PID20
PID19
PID18
PID17
PID16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
PID15
PID14
PID13
PID12
PID11
PID10
PID9
PID8
PID7
PID6
PID5
PID4
PID3
PID2
SYS
FIQ
FIQ, SYS, PID2, .., PID31: Interrupt Mask
0 запрещает прерывание от соответствующего источника. 1 разрешает прерывание от соответствующего источника.
AIC Core Interrupt Status Register
Имя регистра AIC_CISR, он служит для определения состояния прерывания ядра.
Имя регистра AIC_IECR, он служит для разрешения прерываний.
31
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
PID31
PID30
PID29
PID28
PID27
PID26
PID25
PID24
PID23
PID22
PID21
PID20
PID19
PID18
PID17
PID16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
PID15
PID14
PID13
PID12
PID11
PID10
PID9
PID8
PID7
PID6
PID5
PID4
PID3
PID2
SYS
FIQ
FIQ, SYS, PID2, .., PID31: Interrupt Enable
0 записанный ноль не оказывает никакого эффекта. 1 записанная единица разрешает соответствующее прерывание.
AIC Interrupt Disable Command Register
Имя регистра AIC_IDCR, он служит для запрета прерываний.
31
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
PID31
PID30
PID29
PID28
PID27
PID26
PID25
PID24
PID23
PID22
PID21
PID20
PID19
PID18
PID17
PID16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
PID15
PID14
PID13
PID12
PID11
PID10
PID9
PID8
PID7
PID6
PID5
PID4
PID3
PID2
SYS
FIQ
FIQ, SYS, PID2, .., PID31: Interrupt Disable
0 записанный ноль не оказывает никакого эффекта. 1 записанная единица запрещает соответствующее прерывание.
AIC Interrupt Clear Command Register
Имя регистра AIC_ICCR, он служит для очистки прерываний.
31
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
PID31
PID30
PID29
PID28
PID27
PID26
PID25
PID24
PID23
PID22
PID21
PID20
PID19
PID18
PID17
PID16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
PID15
PID14
PID13
PID12
PID11
PID10
PID9
PID8
PID7
PID6
PID5
PID4
PID3
PID2
SYS
FIQ
FIQ, SYS, PID2, .., PID31: Interrupt Clear
0 записанный ноль не оказывает никакого эффекта. 1 записанная единица очищает соответствующее прерывание.
AIC Interrupt Set Command Register
Имя регистра AIC_ISCR, он служит для установки прерываний.
31
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
PID31
PID30
PID29
PID28
PID27
PID26
PID25
PID24
PID23
PID22
PID21
PID20
PID19
PID18
PID17
PID16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
PID15
PID14
PID13
PID12
PID11
PID10
PID9
PID8
PID7
PID6
PID5
PID4
PID3
PID2
SYS
FIQ
FIQ, SYS, PID2, .., PID31: Interrupt Set
0 записанный ноль не оказывает никакого эффекта. 1 записанная единица устанавливает соответствующее прерывание.
AIC End of Interrupt Command Register
Имя регистра AIC_EOICR, регистр окончания прерываний.
31
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
-
-
-
-
-
-
-
-
-
-
-
-
-
-
NIRQ
NIFQ
End of Interrupt Command Register используется в ISR, чтобы показать, что обработка прерывания завершена. В этот регистр может быть записано любое значение, потому что для сигнализации об окончании прерывания нужен только сам факт записи в регистр.
AIC Spurious Interrupt Vector Register
Имя регистра AIC_EOICR, регистр ошибочного прерывания.
31
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
SIQV
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
SIQV
SIQV: Spurious Interrupt Vector Register
Пользователь может сохранить в этот регистр адрес обработчика ошибочного прерывания (spurious interrupt). Записанное значение будет возвращено в AIC_IVR, если произошло spurious-прерывание и значение в AIC_FVR, если произошло spurious fast interrupt.
AIC Debug Control Register
Имя регистра AIC_DEBUG, служит для настройки поведения AIC при отладке.