Примеры прерываний. Механизм приоритетов. Вложенные прерывания

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

Механизм прерывания обеспечивается соответствующими аппаратно-программными средствами компьютера.

Классификация прерываний представлена на рис. 7.1 .


Рис. 7.1.

Запросы аппаратных прерываний возникают асинхронно по отношению к работе микропроцессора и связаны с работой внешних устройств.

Запрос от немаскируемых прерываний поступает на вход NMI микропроцессора и не может быть программно заблокирован. Обычно этот вход используется для запросов прерываний от схем контроля питания или неустранимых ошибок ввода/вывода.

Для запросов маскируемых прерываний используется вход INT микропроцессора. Обработка запроса прерывания по данному входу может быть заблокирована сбросом бита IF в регистре флагов микропроцессора.

Программные прерывания , строго говоря, называются исключениями или особыми случаями. Они связаны с особыми ситуациями, возникающими при выполнении программы (отсутствие страницы в оперативной памяти, нарушение защиты, переполнение ), то есть с теми ситуациями, которые программист предвидеть не может, либо с наличием в программе специальной команды INT n, которая используется программистом для вызова функций операционной системы либо BIOS , поддерживающих работу с внешними устройствами. В дальнейшем при обсуждении работы системы прерываний мы будем употреблять единый термин " прерывание " для аппаратных прерываний и исключений, если это не оговорено особо.

Программные прерывания делятся на следующие типы.

Нарушение (отказ) - особый случай, который микропроцессор может обнаружить до возникновения фактической ошибки (например, отсутствие страницы в оперативной памяти); после обработки нарушения программа выполняется с рестарта команды, приведшей к нарушению.

Ловушка - особый случай, который обнаруживается после окончания выполнения команды (например, наличие в программе команды INT n или установленный флаг TF в регистре флагов ). После обработки этого прерывания выполнение программы продолжается со следующей команды.

Авария ( выход из процесса) - столь серьезная ошибка, что некоторый контекст программы теряется и ее продолжение невозможно. Причину аварии установить нельзя, поэтому программа снимается с обработки. К авариям относятся аппаратные ошибки, а также несовместимые или недопустимые значения в системных таблицах.

Порядок обработки прерываний

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

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

Обработка запросов прерываний состоит из:

  • "рефлекторных" действий процессора, которые одинаковы для всех прерываний и особых случаев и которыми программист управлять не может;
  • выполнения созданного программистом обработчика.

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

Тип прерывания для программных прерываний вводится изнутри микропроцессора; например, прерывание по отсутствию страницы в памяти имеет тип 14. Для прерываний, вызываемых командой INT n, тип содержится в самой команде. Для маскируемых аппаратных прерываний тип вводится из контроллера приоритетных прерываний по шине данных . Немаскируемому прерыванию назначен тип 2.

Всего микропроцессор различает 256 типов прерываний . Таким образом, все они могут быть закодированы в 1 байте.

"Рефлекторные" действия микропроцессора по обработке запроса прерывания выполняются аппаратными средствами МП и включают в себя:

  • определение типа прерывания ;
  • сохранение контекста прерываемой программы (некоторой информации, которая позволит вернуться к прерванной программе и продолжить ее выполнение). Всегда автоматически сохраняются как минимум регистры EIP и CS , определяющие точку возврата в прерванную программу, и регистр флагов EFLAGS . Если вызов обработчика прерывания проводится с использованием шлюза задачи, то в памяти полностью сохраняется сегмент состояния TSS прерываемой задачи;
  • определение адреса обработчика прерывания и передача управления первой команде этого обработчика.

После этого выполняется программа - обработчик прерывания , соответствующая поступившему запросу. Эта программа пишется и размещается в памяти прикладным или системным программистом. Обработчик прерывания должен завершаться командой I RET , по которой автоматически происходит переход к продолжению выполнения прерванной программы с восстановлением ее контекста.

Для вызова обработчика прерывания микропроцессор при работе в реальном режиме использует таблицу векторов прерываний , а в защищенном режиме - таблицу дескрипторов прерываний .


Рис. 7.3.

Содержимое регистра IDTr не сохраняется в сегментах TSS и не изменяется при переключении задачи. Программы не могут обратиться к IDT , так как единственный бит TI индикатора таблицы в селекторе сегмента обеспечивает выбор только между таблицами GDT и LDT .

Максимальный предел таблицы дескрипторов прерываний составляет 256*8 - 1 = 2047.

Можно определить предел меньшим, но это не рекомендуется. Если происходит обращение к дескриптору вне пределов IDT , процессор переходит в режим отключения до получения сигнала по входу NMI или сброса.

В IDT могут храниться только дескрипторы следующих типов:

  • шлюз ловушки ,
  • шлюз прерывания, шлюз задачи.

Бывает такая ситуация, когда надо на один периферийный девайс повесить много разных задач, а он всего один и что то надо с этим делать.

Простой пример — таймер и его прерывание по переполнению.
Мы можем задавать выдержку и по прерыванию делать какие-нибудь операции. Но если в один момент времени мы хотим чтобы таймер по прерванию сделал одну операцию, а потом другую, третью. Да сколько угодно, в зависимости от состояния. А вектор один.

Или, например, USART. Нам запросто может потребоваться, чтобы в зависимости от режима на прерывание по приходу байта выполнялся разный код. В одном режиме — выдача приветствия, в другом посыл матом в баню. В третьем удар в голову. А вектор один.

Конечно, можно добавить в обработчик прерывания switch-case конструкцию и по выбору режима перейти на нужный участок кода, но это довольно громоздко, а самое главное — время перехода будет разное, в зависимости от того в каком порядке будет идти опрос-сравнение switch-case структуры.

То есть в свитче вида:

1 2 3 4 5 6 7 switch (x) { 1 : Действие 1 2 : Действие 2 3 : Действие 3 4 : Действие 4 }

switch(x) { 1: Действие 1 2: Действие 2 3: Действие 3 4: Действие 4 }

Будет последовательное сравнение х вначале с 1, потом с 2, потом с 3 и так до перебора всех вариантов. А в таком случае реакция на Действие 1 будет быстрей чем реакция на Действие 4. Особо важно это при расчете точных временных интервалов на таймере.

Но есть простое решение этой проблемы — индексный переход. Достаточно перед тем как мы начнем ожидать прерывание предварительно загрузить в переменные (а можно и сразу в индексный регистр Z) направление куда нам надо перенаправить наш вектор и воткнуть в обработчик прерывания индексный переход. И вуаля! Переход будет туда куда нужно, без всякого сравнения вариантов.

В памяти создаем переменные под плавающий вектор:

Timer0_Vect_L: .byte 1 ; Два байта адреса, старший и младший Timer0_Vect_H: .byte 1

Подготовка к ожиданию прерывания проста, мы берем и загружаем в нашу переменную нужным адресом

CLI ; Критическая часть. Прерывания OFF LDI R16,low(Timer_01) ; Берем адрес и сохраняем STS Timer0_Vect_L,R16 ; его в ячейку памяти. LDI R16,High(Timer_01) ; Аналогично, но уже со старшим вектором STS Timer0_Vect_H,R16 SEI ; Прерывания ON

Все, можно запускать таймер и ждать нашего прерывания. С другими случаями аналогично.

А обработчик получается вида:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 ;============================= ; Вход в прерывание по переполнению от Timer0 ;============================= TIMER_0: PUSH ZL ; сохраняем индексный регистр в стек PUSH ZH ; т.к. мы его используем PUSH R2 ; сохраняем R2, т.к. мы его тоже портим IN R2,SREG ; Извлекем и сохраняем флаговый регистр PUSH R2 ; Если не сделать это, то 100% получим глюки LDS ZL,Timer0_Vect_L ; загружаем адрес нового вектора LDS ZH,Timer0_Vect_H ; оба байта. CLR R2 ; Очищаем R2 OR R2,ZL ; Проверяем вектор на ноль. Иначе схватим аналог OR R2,ZH ; reset"a. Проверка идет через операцию OR BREQ Exit_Tm0 ; с накоплением результата в R2 ; так мы не портим содержимое Z и нам не придется; загружать его снова IJMP ; Уходим по новому вектору; Выход из прерывания. Exit_Tm0: POP R2 ; Достаем и восстанавливаем регистр флагов OUT SREG,R2 POP R2 ; восстанавливаем R2 POP ZH ; Восстанавливаем Z POP ZL RETI ; Дополнительный вектор 1 Timer_01: NOP ; Это наши новые вектора NOP ; тут мы можем творить что угодно NOP ; желательно недолго - в прерывании же NOP ; как никак. Если используем какие другие NOP ; регистры, то их тоже в стеке сохраняем RJMP Exit_Tm0 ; Это переход на выход из прерывания; специально сделал через RJMP чтобы; Дополнительный вектор 2 ; сэкономить десяток байт на коде возврата:))) Timer_02: NOP NOP NOP NOP NOP RJMP Exit_Tm0 ; Дополнительный вектор 3 Timer_03: NOP NOP NOP NOP NOP RJMP Exit_Tm0

;============================= ; Вход в прерывание по переполнению от Timer0 ;============================= TIMER_0: PUSH ZL ; сохраняем индексный регистр в стек PUSH ZH ; т.к. мы его используем PUSH R2 ; сохраняем R2, т.к. мы его тоже портим IN R2,SREG ; Извлекем и сохраняем флаговый регистр PUSH R2 ; Если не сделать это, то 100% получим глюки LDS ZL,Timer0_Vect_L ; загружаем адрес нового вектора LDS ZH,Timer0_Vect_H ; оба байта. CLR R2 ; Очищаем R2 OR R2,ZL ; Проверяем вектор на ноль. Иначе схватим аналог OR R2,ZH ; reset"a. Проверка идет через операцию OR BREQ Exit_Tm0 ; с накоплением результата в R2 ; так мы не портим содержимое Z и нам не придется; загружать его снова IJMP ; Уходим по новому вектору; Выход из прерывания. Exit_Tm0: POP R2 ; Достаем и восстанавливаем регистр флагов OUT SREG,R2 POP R2 ; восстанавливаем R2 POP ZH ; Восстанавливаем Z POP ZL RETI ; Дополнительный вектор 1 Timer_01: NOP ; Это наши новые вектора NOP ; тут мы можем творить что угодно NOP ; желательно недолго - в прерывании же NOP ; как никак. Если используем какие другие NOP ; регистры, то их тоже в стеке сохраняем RJMP Exit_Tm0 ; Это переход на выход из прерывания; специально сделал через RJMP чтобы; Дополнительный вектор 2 ; сэкономить десяток байт на коде возврата:))) Timer_02: NOP NOP NOP NOP NOP RJMP Exit_Tm0 ; Дополнительный вектор 3 Timer_03: NOP NOP NOP NOP NOP RJMP Exit_Tm0

Реализация для RTOS
Но что делать если у нас программа построена так, что весь код вращается по цепочкам задач через диспетчер RTOS? Просчитать в уме как эти цепочки выполняются относительно друг друга очень сложно. И каждая из них может попытаться завладеть таймером (конечно не самовольно, с нашей подачи, мы же программу пишем, но отследить по времени как все будет сложно).
В современных больших осях на этот случай есть механизм Mutual exclusion — mutex. Т.е. это своего рода флаг занятости. Если какой нибудь процесс общается, например, с UART то другой процесс туда байт сунуть не смеет и покорно ждет пока первый процесс освободит UART, о чем просемафорит флажок.

В моей механизмов взаимоисключений нет, но их можно реализовать. По крайней мере сделать некоторое минимальное подобие. Полноценную реализацию всего этого барахла я делать не хочу, т.к. моей целью является удержания размера ядра на уровне 500-800 байт.
Проще всего зарезервировать в памяти еще один байт — переменную занятости. И когда один процесс захватывает ресурс, то в эту переменную он записывает время когда ориентировочно он его освободит. Время идет в тиках системного таймера которое у меня 1ms.
Если какой либо другой процесс попытается обратиться к этому же аппаратному ресурсу, то он вначале посмотрит на состояние его занятости, считает время в течении которого будет занято и уйдет покурить на этот период — загрузит сам себя в очередь по таймеру. Там снова проверит и так далее. Это простейший вариант.

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

Решение проблемы — добавление еще одной очередной цепочки, на этот раз уже на доступ к ресурсу. Чтобы он не простаивал вообще. Т.е. один выскочил, тут же второй, третий и так далее пока все процессы не справят свою нужду в какой нибудь там USART.
Недостаток очевиден — еще одна очередь это дополнительная память, дополнительный код, дополнительное время. Можно, конечно, извратиться и на очередь к вектору натравить код диспетчера основной цепи. Но тут надо все внимательно отлаживать, ведь вызываться он будет по прерыванию! Да и громоздко, требуется лишь тогда, когда у нас много желающих.

Второе решение — выкинуть переменную времени занятости, оставив только флаг «Занято!». А процесс который пытается обратиться не убегает покурить, а отскакивает на пару шагов назад — на конец очереди задач и сразу же ломится обратно. Народ вокруг сортира не вокруг бегает, а толкется локтями у входа по принципу кто первый пролезет.
Недостаток другой — большая нагрузка на главный конвеер, куча запросов на постановку в очередь так недолго распухнуть на всю оперативку и повстречаться со стеком, а это черевато глобальным апокалипсисом.

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

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

    Фиксирует приоритет любой выполняемой процессором программы.

    Идентифицирует ЗП от ВУ с максимальным приоритетом.

    Разрешает прерывание программы при возникновении запроса с большим приоритетом.

Прерывание программы обслуживания прерываний называется вложенным прерыванием.

Рис. 6.4 Пример работы ЦП в режиме вложенных прерываний.

На рис 6.4 показан пример вложенного прерывания:

    До t 1 нет ЗП

    t 1 → ЗП от ВУ4

    t 2 → ЗП от ВУ3

    t 3 → ЗП от ВУ2

    t 4 → закончено обслуживание ВУ2

    t 5 → ЗП от ВУ1

    t 6 → закончено обслуживание ВУ1

    t 7 → закончено обслуживание ВУ3

    t 8 → закончено обслуживание ВУ4

Недостаток: При большой частоте поступления ЗП ЦП работает неэффективно, т.к. много времени ЦП расходуется на ЗП, восстановление регистров процессора, переход от одной программы к другой.

Можно уменьшить частоту ЗП путем включения буферных ЗУ.

При присвоении приоритетов ВУ учитываются следующие условия:

    Чем больше быстродействие устройства, тем выше приоритет ему присваивается.

    Наивысший приоритет присваивается устройству, данные от которого не могут быть восстановлены (обычно таймер).

    В ЭВМ семейства Macintosh приоритет программы указывается во втором слове ВП.

    В ЭВМ семейства IBM PC приоритет программы устанавливается с помощью специальной БИС (большая интегральная схема) – программируемый контроллер прерываний.

Техническая реализация многоуровневых вложенных приоритетных векторных прерываний в ЭВМ на основе единого магистрального канала обмена данными.

Реализация многоуровневых ВП в ЭВМ семейства IBM .

Для Реализация многоуровневых ВП в ЭВМ семейства IBM применена БИСIntel 8259A .

Технические характеристики бис Intel 8259a.

    Число уровней ЗП = 8.

    Количество уровней можно расширить до 64 за счет каскадного включения микросхем

    Режим обслуживания ЗП, уровни приоритетов, АВП устанавливаются программным путем.

    Техническая реализация приоритетных векторных прерываний в ЭВМ с изолированными магистральными каналами обмена данными (семейство IBM AT ): режимы работы программируемого контроллера прерываний (ПКП),

схема подключения ПКП к системной магистрали,

Схема включения ПКП к системной шине ВУ.

Рис. 6.7 Схема включения ПКП к системной шине и ВУ.

Назначение выводов БИС:

    D 7- D 0 – выводы ШД, служат для приема управляющее информации от ЦП и передачи статусной информации в ЦП.

    A 0 – адресный вход, адресация внутренних регистров контроллера (2 адреса).

    ~ CS (chip select ) - выбор кристалла, разрешает или запрещает связь контроллера с системной шиной.

    • ~CS = 0 – есть связь, ~CS = 1 – нет связи.

Первый ПКП использует адреса – 20 h , 21 h .

Второй ПКП использует адреса – A 0 h , A 1 h .

    ~ RD , ~ WR – ввод, вывод (сигналы ШУ), соединяются с линиями магистрали~ IOR и ~ IOW .

    INT (выход) – сигнал ЗП в ЦП.

    ~INTA (interrupt acknowledge) – сигнал РП от ЦП.

    CAS 2, CAS 1, CAS 0 – шина каскадирования. Для ведущего контроллера прерывания эти линии являются выходами, а для ведомого – входами.

    ~ SP /~ EN – указывает ведущий (1) или ведомый (0) ПКП.

    IR 0... IR 7 – входы запросов прерывания от ВУ.

функциональный состав и программная модель ПКП.

В архитектуре ПЭВМ базовая система ввода/вывода (БСВВ) занимает особое место. Ее можно рассматривать, с одной стороны, как составляющую часть аппаратных средств, с другой стороны, это система является одним из программных модулей ОС.

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

Прерывание - это прекращение выполнения текущей команды или текущей последовательности команд для обработки некоторого события специальной программой - обработчиком прерывания, с последующим возвратом к выполнению прерванной программы.

Событие может быть вызвано особой ситуацией, сложившейся при выполнении программы, или сигналом от внешнего устройства. Прерывание используется для быстрой реакции процессора на особые ситуации, возникающие при выполнении программы и взаимодействии с внешними устройствами.

При прерывании ОС сохраняет состояние процессора – значения регистров и значение счетчика команд (program counter – PC) – адреса прерванной команды. Обработчик прерывания в ОС определяет по содержимому сегмента объектного кода, какого вида прерывание возникло и какие действия по его обработке следует предпринять. Среди возможных видов прерываний, кроме фиксации различных ошибок, имеются также прерывания по таймеру – периодические прерывания через определенный квант времени, предназначенные для опроса устройств (polling) – действий операционной системы по периодической проверке состояния всех портов и внешних устройств, которое может меняться с течением времени: например, к USB-порту была подключена флэшка; принтер закончил печать и освободился, и т.д. ОС выполняет реконфигурацию системы и корректирует системные таблицы, хранящие информацию об устройства



Механизм прерывания обеспечивается соответствующими аппаратно-программными средствами компьютера.

Любая особая ситуация, вызывающая прерывание, сопровождается сигналом, называемым запросом прерывания (ЗП). Запросы прерываний от внешних устройств поступают в процессор по специальным линиям, а запросы, возникающие в процессе выполнения программы, поступают непосредственно изнутри микропроцессора. Механизмы обработки прерываний обоих типов схожи. Рассмотрим функционирование компьютера при появлении сигнала запроса прерывания, опираясь в основном на обработку аппаратных прерываний (рис. 13).

Рис. 13. Выполнение прерывания в компьютере:

tр - время реакции процессора на запрос прерывания;

tс - время сохранения состояния прерываемой программы и вызова обработчика прерывания;

tв - время восстановления прерванной программы.

После появления сигнала запроса прерывания ЭВМ переходит к выполнению программы - обработчика прерывания. Обработчик выполняет те действия, которые необходимы в связи с возникшей особой ситуацией. Например, такой ситуацией может быть нажатие клавиши на клавиатуре компьютера. Тогда обработчик должен передать код нажатой клавиши из контроллера клавиатуры в процессор и, возможно, проанализировать этот код. По окончании работы обработчика управление передается прерванной программе.

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

Время реакции зависит от момента, когда процессор определяет факт наличия запроса прерывания. Опрос запросов прерываний может проводиться либо по окончании выполнения очередного этапа команды (например, считывание команды, считывание первого операнда и т.д.), либо после завершения каждой команды программы.

Прерывания можно разделить на три группы: аппаратные, логические и программные.

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

Логические, или процессорные, прерывания возникают при различных нестандартных ситуациях в работе основного микропроцессора – делении на нуль, переполнении регистров, появлении «точки останова» и др.

Программные прерывания – самая обширная категория. Вырабатываются они, когда одна программа хочет получить определенный сервис со стороны другой программы, причем этот сервис обычно связан с работой аппаратных средств.

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

В аппаратных компонентах машины в самой ДОС и в прикладных программах могут вырабатываться прерывания, которые нужно обслуживать. На БСВВ возлагается задача обслуживания прерываний нижнего уровня – тех, которые требуют непосредственного управления аппаратными компонентами. Этим прерываниям присвоены номера с 0 по 31 (шестнадцатеричные номера 0 – 1F). Другие прерывания – с номерами 32 – 63 (шестнадцатеричные номера 20 – 3F) – относятся к более высокому уровню, и их обслуживание возлагается на другие модули ОС.

В табл. 3 приведен общий перечень прерываний, обслуживаемых БСВВ. В реальных программах на языке ассемблера и в технической литературе по ОС прерывания идентифицируются шестнадцатеричиыми кодами. Из анализа табл. 3 видно, что обслуживаемые БСВВ прерывания соответствуют базовым операциям по управлению внешними устройствами – дисплеем, клавиатурой, НГМД, принтером, коммуникационными каналами. При этом подпрограммы, входящие в БСВВ, выполняют операции нижнего уровня. Так, например, обслуживание НГМД включает возможность начальной установки магнитных головок, проверки текущего статуса устройства, прямого чтения и записи заданных секторов диска, верификации прочитанных или записанных данных и, наконец, форматирования (начальной разметки) дисков.

Таблица 3. Прерывания, обслуживаемые БСВВ

Деся- тичный номер Шестнадца- теричный номер
Деление на ноль
Перевод микропроцессора в пошаговый режим
Падение напряжения питания
Появление точки останова в последовательности команд
Переполнение регистров арифметического устройства
Печать графической копии экрана
Зарезервировано
Зарезервировано
Сигнал от счетчика времени – таймера
Сигнал от нажатия клавиши на клавиатуре
А Зарезервировано
Деся- тичный номер Шестнадца- теричный номер Обслуживаемая ситуация или выполняемая функция
В Зарезервировано
С Зарезервировано
D Зарезервировано
Е Сигнал об окончании обмена с НМД
F Зарезервировано для обслуживания принтера
Управление дисплеем
Запрос списка подсоединенного оборудования
Запрос размера физической памяти
Управление НМД
Управление коммуникационным адаптером
Управление магнитофоном и другими устройствами
Управление клавиатурой
Управление принтером
Обращение к встроенному в ПЗУ бейсику
Перезапуск системы
Запрос/установка текущего времени и даты
1D Адрес таблицы параметров инициализации дисплея.
1E Адрес таблицы параметров НГМД
1F Адрес таблицы символов с кодами 128-255

Некоторые из указанных в табл. 3 прерываний обеспечивают доступ к нескольким взаимосвязанным функциям. Каждая функция идентифицируется своим шестнадцатеричным номером (кодом) и обеспечивает выполнение некоторой частной операции.

Так, например, прерывание 19 (управление НГМД и НМД) открывает доступ к 18 функциям с кодами 0-17):

0 - начальная установка (сброс диска),

1 - выдача текущего статуса диска,

2 - чтение группы (блока) секторов с одной дорожки,

3 - запись группы секторов на одну дорожку,

4 - верификация после чтения или записи,

5 - форматирование дорожки (запись меток секторов),

8 - выдача текущих параметров накопителя,

9 - инициализация таблицы параметров фиксированного диска,

А - «длинное» чтение,

В - «длинная» запись,

С - поиск нужной дорожки,

D - начальная установка диска,

10 - проверка готовности диска,

11 - калибровка диска,

14 - диагностика контроллера,

15 - выдача типа накопителя,

16 - изменение статуса диска,

17 - установка типа накопителя.

Глубина прерывания - максимальное число программ, которые могут прерывать друг друга. Глубина прерывания обычно совпадает с числом уровней приоритетов, распознаваемых системой прерываний. Работа системы прерываний при различной глубине прерываний (n) представлена на рис. 10. Здесь предполагается, что с увеличением номера запроса прерывания увеличивается его приоритет.

Рис. 14. Работа системы прерываний при различной глубине прерываний

При поступлении запроса прерывания компьютер выполняет следующую последовательность действий:

1) определение наиболее приоритетного незамаскированного запроса на прерывание (если одновременно поступило несколько запросов);

2) определение типа выбранного запроса;

3)сохранение текущего состояния счетчика команд и регистра флагов;

4) определение адреса обработчика прерывания по типу прерывания и передача управления первой команде этого обработчика;

5) выполнение программы - обработчика прерывания;

6)восстановление сохраненных значений счетчика команд и регистра флагов прерванной программы;

7) продолжение выполнения прерванной программы.

Этапы 1-4 выполняются аппаратными средствами ЭВМ автоматически при появлении запроса прерывания. Этап 6 также выполняется аппаратно по команде возврата из обработчика прерывания.

Переход к соответствующему обработчику прерывания осуществляется (в реальном режиме работы микропроцессора) посредством таблицы векторов прерываний. Эта таблица располагается в самых младших адресах оперативной памяти, имеет объем 1 Кбайт и содержит значения сегментного регистра команд (CS) и указателя команд (IP) для 256 обработчиков прерываний.

Вектор прерывания – ячейка памяти, содержащая адрес обработчика прерывания.

Вектора прерываний объединяются в таблицу векторов прерываний. Местоположение таблицы зависит от типа и режима работы микропроцессора.

Главные функции механизма прерывания:

1.Распознавание или классификация прерывания.

2. Передача управления обработчику прерывания.

3. Корректное возвращение к прерванной программе

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

Поскольку сигналы прерывания возникают в произвольные моменты времени, то на момент прерывания может существовать несколько сигналов прерывания, которые могут быть обработаны только последовательно. Чтобы обработать сигналы прерывания в разумном порядке им присваиваются приоритеты. Программы, управляя специальными регистрами маски, позволяют реализовать различные дисциплины обслуживания:

Вложенные прерывания.

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

Прерывания в микроконтроллерах представляет собоймеханизм, который позволяет микроконтроллеру реагировать на внешние события. Этот механизм работает таким образом, что при наступлении некоторого события в процессоре возникает сигнал, заставляющий процессор прервать выполнение текущей программы, т.е. говорят, что возникло прерывание. После того как выполнение текущей программы прервано, процессор должен перейти к выполнению программной процедуры, связанной с этим событием (прерыванием) – процедуры обработки прерывания. Однако, прежде чем перейти непосредственно к процедуре обработки прерывания, процессор должен выполнить ряд предварительных действий. Прежде всего, для того чтобы в будущем он смог корректно продолжить прерванную программу, необходимо сохранить состояние процессора (счетик команд, слово состояния процессора, внутренние регистры и т.д.) на момент, предшествующий прерыванию. Т.е. другими словами, требуется сохранить состояния всех тех ресурсов,которые так или иначе могут быть изменены в процессе обработки прерывания. Далее, если в системе имеется несколько возможных источников прерываний (а обычно так и бывает), процессор должен определить источник запроса прерываний. И, наконец, затем перейти к самой процедуре прерываний, конкретной для данного прерывания. По завершению обработки прерывания процессор должен восстановить состояние ресурсов, соответствующее прерванной программе, после чего она может быть продолжена. Следует отметить, что для сохранения всех требуемых ресурсов, поиска источника прерывания и перехода к процедуре обработки прерывания процессор должен затратить вполне определенное время. Это время называется скрытым временем прерывания. Чем меньше скрытое время прерывания, тем выше скорость реакции системы на внешние события и тем выше производительность системы. Во многом это определяется системой прерывания процессора и она является одной из основных особенностей архитектуры контроллера.

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

Одноуровневые прерывания

Данная система прерываний реализована таким образом, что при возникновении прерывания процессор аппаратно переходит к подпрограмме обработки прерываний, расположенной по некоторому фиксированному адресу. Чтобы упростить аппаратную часть системы прерываний, этот адрес обычно располагается либо в начале, либо в конце адресного пространства программной памяти. Поскольку для обработки ВСЕХ прерываний используется только ОДНА точка входа, то такая система прерываний получила название одноуровневой. В такой системе выявление источника прерываний путем опроса состояния флажков признаков прерываний в начале программы обработки прерываний. При обнаружении установленного флажка происходит переход к соответствующему участку процедуры. Чем больше возможных источников прерываний, тем больше времени необходимо для обнаружения источника прерывания. Такой метод обнаружения источника прерывания называется программным опросомили поллингом (polling ). Его недостатком является довольно большое время, затрачиваемое на поиск источника прерывания и, как следствие, замедленная реакция системы на внешние события. Его достоинство – простота реализации системы прерываний.


Векторные прерывания

Чтобы значительно уменьшить время реакции на внешние события, используются многоуровневые или, что то же самое, векторные прерывания. В векторных прерываниях КАЖДОМУ источнику прерывания соответствует СВОЙ, вполне определенный, адрес процедуры обработки прерывания, который принято называть вектором прерывания.

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

PIC vs . AVR vs. MSP vs mcs51. В контроллерах PIC 16 реализована одноуровневая система прерывания. При возникновении прерывания, процессор переходит по адресу 0x0004 (точка входа по прерыванию). Далее, после контекстного сохранения регистров, выполняется программный опрос признаков прерываний (поллинг ). Нужно также отметить, что при обнаружении источника прерывания требуется сбросить соответствующий установленный флажок запроса на прерывания.

В семействе PIC 18 используется как одноуровневая (в режиме совместимости с PIC 16), так и двухуровневая система прерываний. В режиме совместимости при возникновении прерывания процессор переходит к процедуре обработки прерывания по адресу 0x 000008 и далее все происходит аналогично PIC 16. При двухуровневой системе прерывания имеются два вектора перехода 0x 000008 и 0x 000018. Присвоение уровня каждому из имеющихся источников прерывания задается программным путем, с помощью соответствующих признаков. Способ организации системы прерывания (одно- или двухуровневая ) также определяется значением соответствующего разряда в регистре управления прерываниями.

В контроллерах семейства AVR реализована векторная система прерываний. При обнаружении прерывания, процессор сразу переходит по вектору прерывания к процедуре обработки прерываний от данного источника. Вектора прерываний расположены в начальных адресах программной памяти и представляют из себя команду перехода на обработчик прерывания. Количество векторов прерываний соответствует числу возможных источников прерываний, которые зависят от конкретного типа контроллера. Следует добавить, что сброс флажков запроса на прерывания происходит автоматически при переходе по вектору прерывания и выполнение каких-либо инструкций для этого не требуется.

В контроллерах семейства MSP 430 система прерываний также является векторной, т.е. каждому периферийному модулю соответствует свой вектор прерывания. Однако, это не исключает необходимости программного контроля (поллинга ), т.к. некоторые периферийные модули имеют множественные источники прерываний. Пример – прерывания от порта ввода/вывода. В данном случае имеется возможность программно разрешать прерывания от индивидуальных выводов порта. Даже в том случае, если разрешеныпрерывания от более, чем одного входа, они все будут иметь одинаковый вектор прерываний. Определить какой конкретно вход являлся источником прерывания можно только программно. Эта особенность также влияет и на сброс флагов прерываний – флаги прерывания с множественными источниками не сбрасываются автоматически в отличие от флагов прерывания с одним источником. Адрес и количество векторов прерывания зависят от конкретного типа контроллера. Вектора прерываний находятся в конце программной памяти (адресного пространства) и представляют из себя адрес обработчика прерывания.

В контроллерах семейства mcs 51 система прерываний также является векторной, но для вектора прерывания зарезервирован довольно большой обьем памяти (8 байт), что иногда бывает достаточно для его обработчика. Флаги прерывания сбрасываются автоматически при переходе к обработчику прерываний, если у прерывания возможен только один источник и несбрасываются если у прерывания может быть два и более источников. В последнем случае необходимо программно сбросить флаг вызвавший прерывание после выяснения причины прерывания (поллинга ). Вектора располагаются в начальных адресах программной памяти.

Приоритетные прерывания

Обычно, значимость тех или иных событий в системе неодинакова. Одни события более важны и требуют немедленной реакции, другие менее важны, и с ответом на них можно подождать. Естественно, что и соответствующие этим событиям прерывания должны иметь разный приоритет. При одновременном возникновении нескольких прерываний, процессор должен перейти к обработке прерывания, имеющего более высокий приоритет. Этот процесс происходит на аппаратном уровне ядра процессора и называется последовательностью опроса прерываний (interrupt polling sequence ).

PIC vs . AVR vs MSP vs. mcs51. В семействе PIC 16 приоритет опроса того или иного прерывания определяется очередностью опроса соответствующего флажка прерывания. Приоритет опроса прерывания будет выше утех прерываний, у которых флажки запросов на прерывания будут опрашиваться в первую очередь. Порядок опроса флажков признаков прерывания целиком определяется программой обработки прерывания и может быть изменен при ее изменении.

В контроллерах PIC 18 при двухуровневой системе прерывания более высокий уровень приоритетаимеют прерывания с вектором 0x 000008. В пределах одного уровня приоритетность прерывания определяется программно, так же как и у PIC 16.

В семействе AVR приоритета опроса жестко фиксирован и не может быть изменен. Чем меньше адрес вектора прерывания, тем выше уровень опроса прерывания ему соответствующего.

В семействе MSP 430 приоритет опроса также жестко фиксирован и неизменяем, но зависимость приоритета опроса прерывания обратная – чем выше адрес вектора прерывания, тем выше приоритет опроса данного прерывания.

В семействе mcs 51 приоритет опроса полностью анологичен контроллерам семейства AVR .

Вложенные прерывания

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

PIC vs . AVR . В семействе PIC16 процедура обработки любого прерывания начинается с одного и того же адреса и реализовать вложенные прерывания крайне затруднительно, если это вообще возможно.

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

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

Аналогично организована обработка прерываний в семействе MSP . Следует, однако, отметить, что организация программы с вложенными прерываниями требует от программиста особого внимания. Более того, обработка прерывания внутри другого прерывания вообще является нежелательной и должна применяться только в крайних случаях. Ввиду того, что флаги прерываний устанавливаются аппаратно вне зависимости от того, разрешены ли прерывания глобально битом GIE , в большинстве случаев не представляет сложности обработка прерываний без использования вложенности.

В семействе mcs 51 аппаратно предусмотрена возможность вложенных прерываний. Для этого каждому типу прерывания может быть задан уровень приоритета high и прерывание с данным уровнем может прервать обработку другого прерывания с уровнем приоритета low . Приоритеты внутри одного уровня приоритета располагаются согласно последовательности опроса прерываний (interrupt polling sequence ).