Системы прерываний. Примеры прерываний

21.07.2019

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

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

На рис. 2.25 показан выполняемый Поток А. Прерывание IRQx запускает обработчик прерываний Intx, который вытесняется прерыванием IRQy и обработчиком прерываний lnty. Обработчик прерываний Inty возвращает событие, которое запускает Поток В, а обработчик прерываний Intx возвращает событие, которое запускает Поток С.

Вызовы, связанные с прерываниями

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

Посредством этого программного интерфейса поток с соответствующими пользовательскими привилегиями может вызывать функцию InterruptAttachQ или Interrupt Attach EventQ, передавая номер аппаратного прерывания и адрес функции в адресном пространстве потока, которая должна быть вызвана при возникновении прерывания. ОС QNX Neutrino позволяет с каждым номером аппаратного прерывания связывать множество обработчиков прерываний (ISR). Немаскированные прерывания могут обрабатываться во время выполнения уже запущенных обработчиков прерываний.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Рис. 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 – входы запросов прерывания от ВУ.

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

3. Примеры прерываний

3.1. Прерывание по изменению сигнала на портах ввода/вывода (пример в PROTEUS)

3.2. Внешнее прерывание INT (пример в PROTEUS)

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

Итак, какие же существуют прерывания, в микроконтроллере dsPIC33FJ32GP204?

А прерываний в микроконтроллере достаточно много. И все перечислять в данной лекции не имеет смысла. Ведь первое на что мы обращаем внимание, выбирая микроконтроллер – это какие модули в нём есть, а уж потом смотрим, какие прерывания он имеет. Так же и мы будем изучать всё в такой же последовательности. По мере изучения микроконтроллера будем разбирать прерывания различных модулей.

В общем, нужно знать, что для микроконтроллера существует таблица векторов прерываний, которая располагается в памяти программ. Каждое прерывание имеет свой вектор, т. е. адрес начала подпрограммы обработки конкретного прерывания (ISR). Также имеется альтернативная таблица векторов прерывания. При помощи одного бита ALTINV можно указать, из какой таблицы нужно брать адрес подпрограммы прерывания. Т. е. есть альтернатива основной таблице. Но нужно помнить, что бит ALTINV используется сразу для всей таблицы. И если установлена альтернативная таблица, то абсолютно все адреса подпрограммы обработки прерываний, основная программа будет брать из альтернативной таблицы. Альтернативная таблица очень полезна для режима отладки, так как позволяет один раз записать в контроллер программу и при помощи, к примеру, кнопки выбирать между двумя алгоритмами работы программы.

В dsPIC расширили диапазон приоритетов прерываний. Если в PIC18 их было только 2, то в dsPIC уже 8 уровней. И когда я разрабатывал модуль для связи по каналу GPRS, мне это очень пригодилось, так как в микроконтроллере использовалась практически вся имеющаяся на борту периферия, а количество обрабатываемых прерывания было около двадцати.

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

Итак, что же нужно от программиста для работы с прерыванием:

1. Ему нужно разрешить какое-нибудь конкретное прерывание.

2. После того как наступило событие, вызвавшее прерывание, устанавливается флаг соответствующего прерывания, и программа, так сказать, переходит по вектору прерывания. А если нормальным языком сказать: то, как только произойдёт прерывание, так сразу будет вызвана подпрограмма обработки конкретного прерывания.

3. Главное не забыть в подпрограмме прерывания сбросить флаг этого самого прерывания.

Для микроконтроллера dsPIC компилятор С30 предусматривает следующее правило описание подпрограмм обработки прерывания, например для прерывания INT1:

void __ attribute __((__ interrupt __)) _ INT 1 Interrupt ()

Главное нужно обратить внимание на концовку текста заголовка подпрограммы: _ INT 1 Interrupt () – это единственный параметр который обязательно нужно изменять для различных видов прерываний. Для каждого прерывания из таблицы векторов прерывания имеется своё обозначение данного параметра. И тут уж придётся открыть файл помощи к компилятору С30, в частности раздел (у меня это…) «dsPIC30F DSCs (SMPS) Interrupt Vectors» и посмотреть таблицу какое прерывание каким образом должно вызываться. В данной статье приводить эту таблицу не считаю целесообразным, так как у того, кого есть компилятор С30, у того должен быть вложен файл помощи hlpMPLABC30.chm (лично у меня именно так называется). А тем, у кого нет данного компилятора, то и таблица им незачем J. Ладно, отвлеклись…

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

Например, описание прерывания будет выглядеть следующим образом:

void __attribute__((interrupt, auto_psv)) _INT1Interrupt()

Выше был приведён пример заголовка вызова подпрограммы используя адрес основной таблицы. А для альтернативной таблице нужно только в изменяемом параметре после подчёркивания вставить Alt , например:

_ INT 1 Interrupt () -> _ AltINT 1 Interrupt ()

Хочу обратить внимание, хоть подпрограмма прерывания и выглядит как подпрограмма, но объявлять её не нужно, также как и main , так как она объявлена уже компилятором, нужно только правильно написать заголовок подпрограммы обработки прерывания.

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

3.1. Прерывание по изменению сигнала на портах ввода/вывода (CN )

Одно из самых простых для понимания прерывание – это прерывание по изменению состояние на входе CN. В микроконтроллере dsPIC33FJ32GP204 полно таких входов, так что, думаю, это количество удовлетворит любые запросы. Не важно, с какого на какое изменяется состояние на этих каналах («1» -> «0» или «0» -> «1»), это изменение, если оно разрешено, вызовет установление флага «CNIF». Для того, чтобы активизировать прерывание по изменению сигнала, нужно проделать следующие действия:

1. Настроить необходимые каналы CN на вход (с помощью регистра TRISх).

2. Включить контроль изменения сигнала на соответствующем входе CN. Для этого есть аж 2 регистра CNEN1 и CNEN2. Можно как целиком обращаться к каждому регистру для настройки, либо обращаться к соответствующим битам (например _CN15IE=1; _CN6IE=1;)

3. Если необходимо, то включить подтягивающие резисторы. Для этого есть также два регистра CNPU1 и CNPU2. Можно и по отдельности, к примеру _CN15PUE=1; _CN6PUE=1;

4. Разрешить прерывание по изменению сигнала на CN (_ CNIE =1 )

5. Теперь как только изменится сигнал на контролируемых выводах CN, установится флаг прерывания _CNIF. И программа заходит в функцию обработки прерывания. Компилятор С30 для прерывания по изменению сигнала на CN предусмотрел следующее описание функции:

void __ attribute __((__ interrupt __)) _ CNInterrupt ()

Именно здесь происходит обработка данного прерывания (смотреть пример)

6. В подпрограмме обработки прерывания не забываем сбросить флаг прерывания.

Для ознакомления с данным видом прерывания рассмотрим следующий пример. Имеется двигатель и 4 датчика. Когда всё в порядке, то двигатель должен вращаться против часовой стрелки. Но как только состояние датчика изменится (аварийный режим) – двигатель должен немедленно начать вращаться в обратную сторону (по часовой стрелки). А через заданный промежуток времени вновь начать вращаться против часовой стрелки.

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

Собираем схему в PROTEUS

А теперь составляем программу для выполнения поставленной задачи

# include " p 33 Fxxxx . h "

_ FOSCSEL (0 x 02);

_ FOSC (0 xE 2);

char state ; // переменная хранит направление вращения двигателя

// "1" - аварийный режим, "0" - нормальный режим

void init (void );

void init (void )

{ _ CN 8 PUE =1; //включаем подтягивающий резистор на вход CN8 (RС0)

_ CN 10 PUE =1; //включаем подтягивающий резистор на вход CN10 (RС2)

_ CN 17 PUE =1; //включаем подтягивающий резистор на вход CN17 (RС7)

_ CN 19 PUE =1; //включаем подтягивающий резистор на вход CN19 (RС9)

AD 1 PCFGL =0 xffff ;

PORTC =0; // инициализируем порт С

LATC =0;

TRISC =0 xFFFF ; // настраиваем порт C как вход

PORTC =0 xFFFF ;

PORTA =0; // инициализируем порт A

LATA =0;

TRISA =0; // Все вывод настраиваем на выход,

PORTA =0;

_ CN 8 IE =1; // включаем контроль изменения сигнала на

_ CN 10 IE =1; // соответствующих выводах

_ CN 17 IE =1; // если на них изменится сигнал, то

_ CN 19 IE =1; // установится флаг прерывания _CNIF

_ CNIE =1; // разрешаем прерывание INT1

void __ attribute __((__ interrupt __)) _ CNInterrupt ()

state =1; // это аварийный режим

_ CNIF =0; // сбрасываем флаг прерывания по изменению сигнала

void main (void )

{ static long int i ;

init ();

state =0; // считаем, что режим работы при старте нормальный

while (1) // запускаем бесконечный цикл

{ if (state ) // если режим аварийный, то

{ _ CNIE =0; // запрещаем прерывание по изменению сигнала

_ RA 8=0;

_ RA 0=1; // в аварийном режиме

for (i =0; i <210000; i ++) //обеспечиваем задержку

state =0; // активизируем нормальный режим работы двигателя

_ CNIE =1; // разрешаем прерывания CN

{ _ RA 8=1; // в нормальном режиме

_ RA 0=0; // обеспечиваем направления вращения двигателя

} // while(1)

3.2. Внешнее прерывание INT

Если вам необходимо, чтобы ваш микроконтроллер незамедлительно реагировал на действия внешних устройств, то прерывание INT – это то, что вам нужно. В микроконтроллере dsPIC33FJ32GP204 есть три канала INT (INT0, INT1, INT2). Т. е. вы можете для каждого из трёх внешних устройств предусмотреть своё прерывание. Данное прерывание хорошо тем, что оно может вывести контроллер из режима SLEEP. К тому же вам не нужно непрерывно сканировать данные входы, что отнимало бы ресурсы микроконтроллера.

Прерывание INT возникает при изменении сигнала на входе либо «0» -> «1» либо «1» -> «0». Это зависит от состояния бита _INT1EP . Если _INT1EP =1, то по заднему фронту; если _INT1EP =0, то по переднему фронту (например _INT1EP =1 – прерывание INT0 происходит по заднему фронту).

Что касается приоритета, то прерывание INT0 имеет наивысший приоритет, причём в таблице прерываний он является самым первым. Ниже располагаются прерывания INT1 и INT2.

В принципе это и все особенности данного прерывания. Всё остальное как и у других прерываний, т. е. нужно разрешить соответствующее внешнее прерывание. И если произойдёт прерывание, то оно установит соответствующий флаг _INTхIF (например _INT1IF). Не забываем его сбросить. В общем, всё проще простого.

Переходим к примеру

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

Составляем схему в PROTEUS, нам понадобится дополнительно к микроконтроллеру ещё кнопка, пищалка и светодиод.

Думаю на рисунке всё предельно ясно. Перейдём к программе.

#include "p33Fxxxx. h"

// Устанавливаем биты настройки генератора (HS)

_ FOSCSEL (0 x 02);

_ FOSC (0 xE 2);

char state; // "1" - включить звонок, "0" - звонок отключён

void init (void); //объявляем подпрограмму инициализации

// ** подпрограмма инициализация **

void init (void)

{ _CN4PUE=1; //включаем подтягивающий резистор на вход CN4 (RB0)

AD1PCFGL=0xffff; // все выводы как цифровые I/O

PORTB=0x00; // инициализируем порт В

LATB=0;

TRISB=0x0001; // вывод RB0 настраиваем на вход

PORTB=0x00;

// инициализации порта C.

PORTC=0;

LATC=0;

TRISC=0; //устанавливаем все выводы как выход

PORTC=0;

RPINR0=0x0000; // сигнал INT1 настраиваем, чтобы снимать с вывода RP0 (RB0) (данная

// команда не для всех dsPIC

_INT1EP=1; // прерывание INT1 происходит по заднему фронту

_INT1IE=1; // разрешаем прерывание INT1

// ******* подпрограмма обработки прерывания *

void __ attribute __((__ interrupt __)) _ INT 1 Interrupt ()

state =1; // необходимо включить звонок

_ INT 1 IF =0; // сбрасываем флаг прерывания INT1

// **** Точка входа в программу *

void main (void )

{ static long int i ; //объявляем переменную, чтобы организовать задержку

init(); // вызываем подпрограмму инициализации

state=0; // вначале звонок должен быть выключен

while(1) // запускаем бесконечный цикл

{ if (state) // если state равен "1", то

{ _RC0=1; // зажигаем светодиод

_RC2=1; // включаем пищалку

for(i=0;i<160000;i++) // задержка, обеспечивает определённое время звучания

state=0; // указываем, что пищалку нужно отключить

else // иначе, если state равна "0", то

{ _RC0=0; // гасим светодиод

_RC2=0; // прекращаем звуковой сигнал

} // while(1)

Аналогично работать и с прерываниями INT0 и INT2. В дальнейших примерах мы ещё не раз будем пользоваться этими прерываниями.

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

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

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

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

При прерывании ОС сохраняет состояние процессора – значения регистров и значение счетчика команд (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. Корректное возвращение к прерванной программе

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

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

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

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

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

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

1. разрешить прерывание по команде EI

2. временно запомнить приоритет прерванной программы

3. загрузить в схему приоритетных прерываний новый текущий приоритет

4. обслужить это прерывание

5. восстановить прежний приоритет

6. восстановить прерванную программу (командой IRET)

Аппаратные прерывания:

Внутренние (от процессора и сопроцессора)

Внешние:

Маскируемые

Немаскируемые

Программно-вызываемые прерывания

К внутренним прерываниям можно отнести и программно-вызываемые пре­рывания. Внутренние прерывания МП генерируются при возникновении особых условий при выполнении текущей команды (пример: деление на нуль переполнение разрядной сетки и т.п.).

Програмно-вызываемые прерывания выполняются под действием команды INT, и в этом случае действия МП аналогичны вызову программы ISR, т.е. сохранение в стеке адреса возврата, передача управления по указанному ад­ресу, но имеются и некоторые отличия:

A) выполняется прерывание, помещенное в стек и в регистре флагов сбрасы­вается в 0 бит IF (разрешения обработки прерываний).

Б) вместо адреса вызываемой подпрограммы аргументом вызова является номер вектора прерываний.

B) по окончании выполнения процедуры програмно-вызываемого прерыва­ния процессор извлекает из стека кроме адреса возврата и сохраненное зна­чение регистра флагов. Программо-вызываемые прерывания позволяют лег­ко и быстро вызывать процедуры из любого сегмента памяти, не применяядальних вызовов. Например, программное прерывание INT3 традиционно используется в целях отладки программ для создания точки останова и оно вызывается однобайтной инструкцией.