Настройка контроллера
Перед началом работы все контроллеры должны быть настроены. Для этого на каждыйВН59 надо последовательно подать три или четыре команды инициализации (ICW1 – ICW4). Три команды подаются, если в системе один контроллер прерываний, четыре – если несколько. Если в системе несколько контроллеров, вначале настраивается MASTER, а затем SLAVE. Рассмотрим далее форматы настроечных команд.
ICW1 передается при А0=0 и имеет формат, приведенный на рис. 6.
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
LTIM | SNGL | IC4 |
Рис. 6. Формат ICW1.
При LTIM = 1запросы на IR7-0 воспринимаются по уровню сигнала, при LTIM = 0 – по фронту сигнала.
Если SINGL = 0 – в системе несколько контроллеров и, следовательно, будет команда инициализации ICW3. При SINGL = 1– в системе один контроллер и ICW3 передаваться не будет.
При IC4 = 1 будет команда ICW4, при IC4 = 0ICW4 не будет.
Например, в системе один контроллер прерываний. Тогда типичная последовательность команд, задающая контроллеру ICW1, выглядит так:
Mov al, 00010011b
Out 20h, al
ICW2 передается при А0=1 и имеет формат, приведенный на рис.7. Здесь Т7-Т3 – старшие пять разрядов типа прерывания, а звездочки означают безразличное состояние бита.
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
T7 | T6 | T5 | T4 | T3 | * | * | * |
Рис. 7. Формат ICW2.
По сути дела, передавая контроллеру ICW2, мы задаем тип ножке IR0, причем этот тип всегда кратен восьми (0 или 8 или 16 …). Типы всех остальных ножек контроллер формирует автоматически, прибавляя к типу IR0 по единице. То есть, если у IR0 тип 8, то у IR1 тип 9, у IR2 тип 10 и так далее.
Например, хотим задать IR0 тип 16 (00010000 = 00010***):
Mov al, 16
Out 21, al
ICW3 передается при А0 = 1. Формат ICW3 различается для ведущего и ведомых контроллеров. Для ведущего: если в i-ом разряде ICW3 стоит единица, значит к линии IRi подключен ведомый контроллер. Для ведомого ICW3 имеет формат, приведенный на рис 8.
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
ID2 | ID1 | ID0 |
Рис. 8. Формат ICW3 для SLAVE.
ID2-0 задают номер ножки ведущего, к которой подключен данный ведомый контроллер.
Например, в системе три контроллера: Master, Slave1 и Slave2. Slave1 подключен к ножке IR4, а Slave2 – IR1 Masters. Тогда:
; ICW3 для Master
Mov al, 00010010b
Out 21h, al
; ICW3 для Slave1
Mov al, 00000100b
Out 0a1h, al
; ICW3 для Slave2
Mov al, 00000001b
Out address_slave2, al
ICW4 передается при А0=1 и обычно имеет формат (несколько упрощенный), приведенный на рис. 9.
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
SFNM | AEOI |
Рис. 9. Формат ICW4.
AEOI = 1– автоматическое окончание прерываний (не нужна команда EOI). AEOI = 0– обычное окончание прерываний (нужна команда EOI).
SFNM = 0– обычный полновложенный режим. SFNM = 1- специальный полновложенный режим.
Например, типичная передача ICW4:
Mov al, 00000001b
Out 21h, al
При необходимости внести изменения в настройки контроллера необходимо выдать на него заново всю последовательность команд инициализации,, начиная с ICW1 и заканчивая ICW4.
В заключение этого раздела приедем программу, которую выполняет BIOS при инициализации контроллеров прерываний IBM PC:
;для Master
Mov al, 11h
Out 20h, al
Mov al, 8
Out 21h, al
Mov al, 4
Out 21h, al
Mov al, 1
Out 21h, al
;для Slave
Mov al, 11h
Out 0a0h, al
Mov al, 70h
Out 0a1h, al
Mov al, 2
Out 0a1h, al
Mov al, 1
Out 0a1h, al
Управление контроллером
После того как ВН59 настроен, все остальные настроечные слова он воспринимает как команды управления. Всего имеется три таких команды. Обычно их обозначают OCW1, OCW2 и OCW3.
OCW1передается при А0 = 1. Если в i-ом разряде OCW1 стоит единица, вход IRi контроллера маскируется и запросы на этом входе ВН59 восприниматься не будут до тех пор, пока программист его не размаскирует.
Например, хотим блокировать клавиатуру и подсчет системного времени в IBM PC. Запрос на прерывание от клавиатуры заведен на вход IR1, а запрос от таймера (системное время) – на вход IR0 Masters. Тогда для блокирования:
Mov al, 00000011b
Out 21h, al
Для разблокирования:
Mov al, 0
Out 21h, al
Во избежание конфликтов всем входам IR контроллера присваиваются приоритет. Если программист не задает приоритеты линий IR, по умолчанию линии IR0 присваивается старший, а линии IR7 – младший приоритет. Команда OCW2 (передается при А0 = 0) позволяет гибко манипулировать приоритетами линий IR. Формат OCW2 приведен на рис. 10.
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
R | SL | EOI | L2 | L1 | L0 |
Рис. 10. Формат OCW2.
EOI– обычное окончание прерывания. SL– разрешение/запрещение разрядов L2-0. R– ротация (вращение) приоритетов. L2-0–номер ножки IRi.
Далее рассмотрим возможные варианты команды OCW.
Обычная команда EOI. Имеет формат:
Если не задано автоматическое окончание прерываний (бит AEOI в ICW4 не равен единице), контроллер, восприняв запрос на ножке IRi и получив подтверждение этого прерывания от процессора (сигнал INTA), устанавливает бит ISRi в своем регистре ISR. Пока этот бит установлен, он блокирует восприятие запросов, на ножке IRi и всех менее приоритетных ножках (поставлена «штора»). Сделано это для того, чтобы менее приоритетные запросы не прерывали обработку более приоритетных. Пусть, например, IR0 имеет старший приоритет, а IR7 – младший и воспринят запрос на ножке IR2. Бит ISR2 будет установлен, а процессор начнет выполнять обработчик для запроса по IR2. Пусть, до завершения этого обработчика, пришло еще два запроса, сначала по IR6, затем по IR1. Запрос по IR6 воспринят не будет (менее приоритетный), а по IR1 будет. Процессор прервет выполнение обработчика для IR2 и перейдет на обработчик IR1, а контроллер установит еще один бит – ISR1.
Собственно говоря, установленный бит ISRi означает, что запрос по ножке IRi в данный момент обслуживается. По окончании этого обслуживания соответствующий бит ISR необходимо сбросить и сделать это должен программист, выдав (как правило, в конце обработчика) на контроллер команду EOI. Например, в конце обработчика запроса от клавиатуры должны стоять команды:
Mov al, 20h
Out 20h, al
Если такие команды в обработчике отсутствуют, после первого же нажатия клавиши клавиатуры у нас «не будет», а заодно «не будет» и многих менее приоритетных устройств, таких как COM порты и другие.
Действие команды EOI заключается в том, что она сбрасывает самый приоритетный из установленных битов ISR. Если контроллер был настроен на автоматический конец прерываний, биты ISR при восприятии запросов не устанавливаются («штора» не ставится) и команда EIO не нужна. Но режим автоматического конца прерываний – довольно опасный режим, поскольку может сопровождаться неприятными эффектами, например, переполнением стека. Поэтому на практике почти всегда используется обычный конец прерывания.
Специальная команда EOI. Формат команды:
01100L2L1L0.
Разряды L2-0 задают номер бита ISR, который должен быть сброшен.
Некоторые манипуляции с приоритетами, например использование рассматриваемого ниже режима спецмаскирования, могут порождать ситуации, когда менее приоритетный обработчик завершается раньше более приоритетного. Использование в такой ситуации обычной команды EOI приведет к сбросу «не того» ISR. Поэтому приходится указывать контроллеру конкретный ISR, который надо сбросить. Например, в конце обработчика запроса по IR3:
Mov al, 01100011b
Out 20h, al
Ротация приоритетов по обычной команде EOI. Формат команды:
10100000.
Сбрасывает наиболее приоритетный ISRi после чего входу IRi автоматически присваивается самый низкий приоритет, а приоритеты остальных входов IR проворачиваются по кольцу. Например, старший приоритет у IR0, младший у IR7. Обработчик для IR6 завершается. При этом выполняются команды:
Mov al, 10100000b
Out 20h, al
После их выполнения ISR6 будет сброшен, старший приоритет будет у IR7, младший у IR6. Ротация приоритетов применяется для «равномерного» обслуживания запросов. При отсутствии ротации запросы с низким приоритетом обслуживаются медленнее, чем запросы с высоким приоритетом.
Автоматическая ротация приоритетов. Используется только в режиме автоматического конца прерывания.Формат команды:
10000000.
После получения контроллером такой команды, по подтверждению процессором любого запроса, приоритеты входов IR автоматически проворачиваются по кольцу влево на одну позицию. Например, было: IR0 – старший, IR7 – младший. После первого запроса: IR7 – старший, IR6 – младший. После второго запроса: IR6 – старший, IR5 – младший. И так далее.
Отменить автоматическую ротацию можно послав в контроллер OSW2 формата:
00000000.
Команда установки приоритета. Формат команды:
11000L2L1L0.
Присваивает ножке IRi, номер которой задан разрядами L2-0, низший приоритет. Приоритеты остальных ножек проворачиваются по кольцу. Например, команды
Mov al, 11000100b
Out 20h, al
присваивают IR4 младший приоритет, старший будет у IR5.
Ротация по специальной команде EOI. Формат команды:
11100L2L1L0.
Объединяет функции двух команд: установки приоритетов и специальной команды EOI. Присваивает ножке IRi, номер которой задан разрядами L2-0, низший приоритет. Приоритеты остальных ножек проворачиваются по кольцу. Сбрасывает в ISR бит, заданный разрядами L2-0.
Отметим, что в IBM PC активно используется обычная команда EOI, остальные варианты OCW2 используются крайне редко.
Команда OCW3 (передается при А0 = 0) используется, например тогда, когда обработчику для принятия какого-либо решения требуется прочитать содержимое одного из внутренних регистров контроллера. Формат OCW3приведен на рис. 11.
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
ESMM | SMM | P | RR | RIS |
Рис. 11. Формат OCW3.
ESMMи SMMработают в паре. Комбинация ESMM = 1, SMM = 1 переводит контроллер в режим специального маскирования. Комбинация ESMM = 1, SMM = 0 сбрасывает режим специального маскирования. При ESMM = 0 бит SMM игнорируется. Режим спемаскирования применяется, если необходимо разрешить запросам с низким приоритетом прерывать выполнение обработчиков высокоприоритетных прерываний. По сути дела, при спецмаскировании отменяется действие «шторы», хотя биты ISR могут быть установлены.
RRи RISтакже работают в паре. При RR = 1, RIS = 0 разрешается чтение регистра IRR. При RR = 1, RIS = 1 разрешается чтение регистра ISR. Чтение осуществляется по следующей схеме. Сначала в контроллер посылается соответствующая команда OCW3 (константа 0ah для чтения IRR и 0bh для чтения RIS). Затем выполняется команда in. Например, хотим прочитать RIS Master и IRR Slave:
;для Master
Mov al, 0bh
Out 20h, al
Nop
In al, 20h
;для Slave
Mov al, 0ah
Out 0a0h, al
Nop
In al, 0a0h
После того как соответствующая команда на контроллер подана, читать содержимое выбранного регистра можно неоднократно, используя только команду in. При инициализации контроллера по умолчанию выбирается IRR, то есть исходно к IRR можно обращаться просто командой in, без передачи OCW3. При RR = 0 бит RIS игнорируется.
Прочитать содержимое регистра IMR можно в любой момент просто командой in, поскольку IMR отождествляется с другим системным адресом. Например, хотим прочитать IMR Master:
In al, 21h
При P= 1 устанавливается режим опроса. В этом режиме предполагается, что процессор не воспринимает запросы на прерывание, то есть вход INTR процессора замаскирован. В то же время текущую программу «интересует» имеются ли запросы от внешних устройств и какие. Если подать на контроллер OCW3 c P = 1, то по следующей команде in (конечно с правильным адресом)в al попадет байт, формат которого показан на рис. 12.
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
I | * | * | * | * | W2 | W1 | W0 |
Рис. 12.Формат байта опроса.
При I= 1 есть запросы, при I = 0 нет. При наличии запросов биты W2-0 задают номер ножки IRi для самого приоритетного из них. Приведем пример реализации режима опроса для Master:
Mov al, 100b
Out 20h, al
Nop
In al, 20h
При Р = 1 чтение из IRR и ISR невозможно.
Режим, в котором установленный в регистре ISR бит ISRi блокирует восприятие запросов на входах IRi и менее приоритетных («штора») называется режимом полного вложения. Именно он, как правило, и используется на практике. Но при каскадном соединении контроллеров у этого режима имеется недостаток. Пусть на вход Slave с самым низким приоритетом пришел запрос. Slave передаст его на ножку IRi Master, к которой Slave подключен. Master установит у себя в регистре ISR бит ISRi, заблокировав тем самым запросы от Slave. Теперь, до тех пор пока бит ISRi не будет сброшен, Master не будет воспринимать никакие запросы от Slave, даже если они более приоритетные. Для решения этой проблемы можно использовать режим специального полного вложения. Этот режим задается контроллеру при настройке в команде инициализации ICW4 (смотри рис. 9). Его отличие заключается в том, что бит ISRi блокирует восприятие запросов только на менее приоритетных ножках IR, а ножка IRi остается незамаскированной. Однако, режим специального вложения достаточно опасен, поскольку в нем возможна ситуация «сверхвложения» - частые многократные запросы на одной и той же ножке могут привести к переполнению стека.