Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Адаптеры и контроллеры ЭВМ.docx
Скачиваний:
0
Добавлен:
30.12.2019
Размер:
844.13 Кб
Скачать

Irq2 ведущего). На входы irq0, irq1, irq3-irq7 ведущей микросхемы и на входы irq8-irq15 ведомой

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

приоритетом, после чего контроллер вырабатывает сигнал INT и передает в процессор номер вектора

прерывания.

Рис. 1. Традиционный порядок подключения внешних устройств к контроллеру прерываний

Номер вектора формируется контроллером прерывания путем сложения базового значения (записанного

в соответствующий регистр контроллера на стадии инициализации системы) и номера линии, на которую

поступил запрос (ведущей микросхеме IRQ0 соответствует линия 0, IRQ7 — линия номер 7; ведомой

микросхеме IRQ8 соответствует линия 0, IRQ15 — линия 7). Базовый вектор ведущей микросхемы в

реальном режиме DOS имеет значение 08h, базовый вектор ведомой — 70h. Соответственно, ведущая схема

вырабатывает вектора с номерами 08h-0Fh, ведомая — с номерами 70h-77h (табл. 1). Приоритеты запросов

прерывания (по убыванию) располагаются в следующем порядке: IRQ0, IRQ1, IRQ8 - IRQ15, IRQ3 - IRQ7.

Все последующие модели АТ-совместимых компьютеров вынуждены имитировать работу микросхем

I8259a с целью сохранения совместимости со старым программным обеспечением. Большая часть

возможностей указанных микросхем, к счастью для программистов, не используется в АТ-совместимых

персональных компьютерах: приоритеты прерываний, поступающих от периферийных устройств, и адреса

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

Полностью перепрограммировать контроллер приходится только при переключении процессора в

защищенный режим, так как при этом необходимо изменить номера векторов прерываний, а работа с

контроллером в обычном реальном режиме DOS требует выполнения только двух типов операций:

· маскирование и размаскирование прерываний по отдельным линиям;

· посылка команды завершения обработки прерывания контроллеру.

Чтобы маскировать (запретить) прерывание, необходимо установить в 1 соответствующий ему бит в

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

маске должен быть изменен только один разряд, а остальные нужно сохранить в исходном состоянии, то

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

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

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

поскольку контроллер по сравнению с процессором работает слишком медленно. Регистр маски прерываний ведущего контроллера доступен для записи и считывания через порт 21h, ведомого контроллера — через

порт Alh.

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

контроллер, линия № 1), нужно выполнить следующий ряд команд:

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

обратную операцию — размаскировать линию сигнала запроса от соответствующего устройства. Например,

для драйвера мыши PS/2-типа, обрабатывающего прерывание IRQ12 (ведомый контроллер, линия № 4),

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

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

проверка маски, и если запрос не запрещен, то происходит проверка его приоритета. Если нет других

запросов или данный запрос имеет наивысший приоритет, то контроллер посылает микропроцессору сигнал

запроса INT. Если маскируемые прерывания разрешены (установлен флаг IF в регистре флагов процессора),

то процессор выдает контроллеру сигнал подтверждения прерывания INTA. После получения сигнала INTA

контроллер выдает процессору номер вектора прерывания и переводит запрос в разряд обслуживаемых

(соответствующий бит в регистре поступивших запросов контроллера сбрасывается, а бит в регистре

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

записывает в стек содержимое регистра флагов, адрес очередной команды прерываемой программы и

сбрасывает флаг IF. В результате перечисленных выше действий в момент начала обработки прерывания все

маскируемые прерывания в процессоре запрещены, а контроллер не пропускает запросы прерываний,

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

прерывания от устройства, запрос которого поступил на обработку, также будут заблокированы

контроллером. Процессор должен разрешить обработку маскируемых прерываний (установить флаг IF

командой STI), как только будет выполнен критический участок кода процедуры обработки прерывания, то

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

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

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

Разрешить контроллеру обрабатывать прерывания с таким же или более низким приоритетом следует

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

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

необходимо послать контроллеру команду EOI (End Of Interrupt), код которой в шестнадцатеричном виде

имеет значение 20h. Регистр команд ведущей микросхемы доступен для записи через порт 20h, регистр

команд ведомой — через порт A0h. Например, в процедуру обработчика прерывания от клавиатуры

обязательно должна быть включена последовательность команд:

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

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

команду EOI не только в ведомый, но и в ведущий контроллер: