Особенности обработки аппаратных прерываний
Аппаратные прерывания вырабатываются устройствами компьютера, как правило, при завершении ими операций обмена данными или при изменении состояния. В зависимости от типа устройства обработчик прерывания может выполнять те или иные функции. Например, по прерыванию таймера соответствующий обработчик увеличивает содержимое счетчика, расположенного в оперативной памяти. По содержимому этого счетчика программы могут определить текущее время.
В отличие от программных прерываний, вызываемых запланировано программой или драйвером, аппаратные прерывания всегда происходят асинхронно по отношению к выполняющимся программам. Кроме того, может возникнуть одновременно сразу несколько прерываний!
Для того чтобы система "не растерялась", решая какое прерывание обслуживать в первую очередь, существует специальная схема приоритетов. Каждому прерыванию назначается свой приоритет. Если происходит одновременно несколько прерываний, система отдает предпочтение самому высокоприоритетному, откладывая на время обработку остальных прерываний.
Система приоритетов реализована на двух микросхемах Intel 8259 (или аналогичных). Каждая микросхема является контроллером прерывания и обслуживает до восьми приоритетов. Микросхемы можно объединять (каскадировать) для увеличения количества уровней приоритетов в системе.
Уровни приоритетов обозначаются сокращенно IRQ0 - IRQ15 .
В компьютере типа IBM PC/XT была установлена только одна микросхема контроллера прерывания. Приоритеты линейно зависели от номера уровня прерывания. Прерывание IRQ0 соответствовало самому высокому приоритету, за ним шли прерывания IRQ1 , IRQ2 , IRQ3 и так далее.
Прерывание IRQ2 в компьютерах IBM PC/XT было зарезервировано для дальнейшего расширения системы. В компьютерах IBM PC/AT прерывание IRQ2 стало использоваться для каскадирования двух контроллеров прерывания 8259. Добавленные приоритетные уровни прерываний IRQ8 - IRQ15 в этих компьютерах располагаются по приоритету между прерываниями IRQ1 и IRQ3 .
Приведем список аппаратных прерываний, расположенных в порядке убывания приоритета:
Номер | Описание |
IRQ0 - прерывание интервального таймера, возникает 18,2 раза в секунду | |
IRQ1 - прерывание от клавиатуры | |
A | IRQ2 - используется для каскадирования аппаратных прерываний |
IRQ8 - прерывание от часов реального времени | |
IRQ9 - прерывание от контроллера EGA | |
IRQ10 - зарезервировано | |
IRQ11 - зарезервировано | |
IRQ12 - зарезервировано | |
IRQ13 - прерывание от арифметического сопроцессора | |
IRQ14 - прерывание от контроллера жесткого диска | |
IRQ15 - зарезервировано | |
B | IRQ3 - прерывание асинхронного порта COM2 |
C | IRQ4 - прерывание асинхронного порта COM1 |
D | IRQ5 - прерывание от контроллера жесткого диска (только в компьютерах IBM PC/XT) |
E | IRQ6 - прерывание генерируется контроллером НГМД |
F | IRQ7 - прерывание принтера |
Из этого списка видно, что самый высокий приоритет у прерываний от интервального таймера, затем идет прерывание от клавиатуры. Наименьший приоритет имеет прерывание принтера.
Для управления схемами приоритетов необходимо знать внутреннее устройство контроллера прерываний 8259.
Поступающие прерывания запоминаются в регистре запроса на прерывание IRR. Каждый бит из восьми в этом регистре соответствует своему прерыванию.
Перед выдачей в процессор запроса на прерывание проверяется содержимое восьмибитового регистра маски прерываний IMR. Если прерывание данного уровня не замаскировано, то запрос на прерывание выдается.
Наиболее интересными с точки зрения программирования контроллера прерываний являются регистры маски прерываний IMR и управляющий регистр прерываний.
В компьютерах IBM PC/XT регистр маски прерываний имеет адрес 21h, управляющий регистр прерываний - 20h. В компьютерах IBM PC/AT первый контроллер 8259 имеет такие же адреса, что и в IBM PC/XT. Регистр маски прерываний второго контроллера имеет адрес A1h, управляющий регистр прерываний - адрес A0h.
Разряды регистра маски прерываний соответствуют номерам IRQ. Для того чтобы замаскировать аппаратное прерывание какого-либо уровня, надо записать в регистр маски байт масок. В этом байте следует установить в 1 те биты, которые соответствуют маскируемым прерываниям . Например, для маскирования прерываний от НГМД в порт 21h надо записать двоичное число 01000000.
Приведем строку программы, маскирующей прерывание от флоппи-диска:
outp(0x21, 0x40);Чтобы "оживить" прерывания от НГМД , используйте следующую строку (которая размаскирует все прерывания):
outp(0x21, 0);Заметьте, что в приведенном выше примере мы замаскировали прерывание именно от НГМД , все остальные устройства продолжали нормально работать. Если бы мы выдали машинную команду CLI, то отключились бы все аппаратные прерывания. Это привело бы, например, к тому, что клавиатура была бы заблокирована.
Еще одно замечание, касающееся обработки аппаратных прерываний.
Если вы полностью заменяете стандартный обработчик аппаратного прерывания, не забудьте в конце программы записать байт 20h в порт с адресом 20h (A0h для второго контроллера 8259). Эти действия необходимы для очистки регистра обслуживания прерывания ISR. При этом разрешается обработка прерываний с более низким приоритетом чем то, которое только что обрабатывалось.
Если вы обрабатываете прерывание 1Ch, то указанная выше добавка в конце программы обработки прерывания не нужна, так как это прерывание является программным и вызывается из обработчика аппаратного прерывания таймера.
Перед тем как завершить изучение прерываний, зададимся вопросом - можно ли замаскировать немаскируемое прерывание ? Оказывается можно!
Конечно, если сигнал прерывания пришел на вход немаскируемого прерывания процессора, ничего сделать нельзя - прерывание произойдет неизбежно. Но в компьютере предусмотрены схемы, блокирующие вход немаскируемого прерывания процессора NMI.
Для компьютера IBM PC/XT маскированием немаскируемого прерывания управляет порт с адресом 0A0h. Если записать в него 0, немаскируемое прерывание будет запрещено, если 80h - разрешено.
Аналогично для IBM PC/AT маскированием немаскируемого прерывания управляет бит 7 порта 70h. Запись байта 0ADh в порт 70h запретит немаскируемое прерывание, а байта 2Dh - разрешит прохождение прерывания.
Заметим, что мы не запрещаем немаскируемое прерывание "внутри" процессора - это невозможно по определению, мы "не пускаем" сигнал прерывания на вход NMI.