Прерывания
Прерывания (аппаратные) – это сигналы, при поступлении которых нормальная последовательность выполнения программы может быть прервана, при этом система запоминает информацию, необходимую для возобновления работы прерванной программы, и передает управление подпрограмме обработки прерывания (ISR, Interrupt Service Routine). По завершению обработки, как правило, управление возвращается прерванной программе.
Все прерывания можно разделить на три основных типа:
· аппаратные прерывания от периферийных устройств;
· внутренние аппаратные прерывания (называемые также исключениями, exceptions);
· программные прерывания.
В подавляющем большинстве ОС обработку всех прерываний берет на себя сама система, поскольку это слишком «интимная» часть работы, способная повлиять на функционирование всех системных и прикладных программ.
Поскольку типы и разновидности прерываний весьма многообразны и каждый из них требует особой обработки, большинство процессоров поддерживает векторные прерывания. Это означает, что каждая разновидность прерывания имеет свой номер, и этот номер используется как индекс в массиве, хранящем адреса ISR для всех прерываний. При возникновении прерывания аппаратура компьютера по номеру прерывания определяет адрес подпрограммы обработки и вызывает ее.
Для того чтобы некоторые наиболее ответственные участки системных программ выполнялись без прерываний, система имеет возможность временно запретить прием большинства прерываний. Такой запрет должен устанавливаться лишь на короткие интервалы времени, не более нескольких миллисекунд.
Программные прерывания вызываются выполнением специальной команды, но обрабатываются точно так же, как остальные типы прерываний. По сути, команда программного прерывания представляет собой особый случай вызова подпрограммы, но при этом вместо адреса подпрограммы указывается номер прерывания, обработчик которого должен быть вызван. В большинстве современных ОС программные прерывания используются для перехода из режима пользователя в режим ядра при вызове системных функций из прикладной программы.
Одним из важнейших источников прерываний являются периферийные устройства. Как правило, устройство генерирует сигнал прерывания в одном из двух случаев:
· при переходе в состояние готовности;
· при возникновении ошибки выполнения операции.
Состояние готовности – это такое состояние устройства, в котором оно готово принять и выполнить команды от процессора. Для устройства ввода готовность означает наличие в устройстве данных, которые могут быть переданы в процессор (например, клавиатура переходит в состояние «Готово» при нажатии клавиши и возвращается в состояние «Не готово», когда код нажатой клавиши считан в процессор). Для устройства вывода готовность – это возможность принять от процессора данные, которые следует вывести. Например, матричный принтер принимает символы, которые нужно напечатать, в свой внутренний буфер. Если буфер полон, принтер переходит в состояние «Не готово» до тех пор, пока часть символов будет напечатана и в буфере освободится место. Дисковый накопитель при начале выполнения новой операции чтения или записи на диск переходит в состояние «Не готово», а после завершения операции возвращается в состояние «Готово». В любом из этих случаев переход в состояние «Готово» – это повод для устройства напомнить о себе процессору: обратите на меня внимание, я к вашим услугам! Для этого и служит сигнал прерывания.
Ошибка операции также требует вмешательства системы или пользователя. Например, при ошибке отсутствия бумаги в лотке принтера система должна оповестить об этом пользователя; при ошибке чтения с диска либо система, либо пользователь должен решить, что делать: повторить операцию, завершить программу или продолжить выполнение.
Не каждое устройство генерирует прерывания. Например, монитор ПК не выдает прерываний: он «всегда готов», т.е. всегда может принять данные для отображения, и он «никогда не ошибается», точнее сказать, его неисправность обнаруживается «на глаз».
2.4. Архитектура подсистемы ввода/вывода
С программной точки зрения, устройство (или его контроллер) обычно представлено одним или несколькими регистрами. Регистр устройства – это адресуемое машинное слово, используемое для обмена данными или сигналами между устройством и процессором. Можно выделить два основных типа регистров.
· Регистр данных служит для обмена данными. Запись данных в такой регистр (если она возможна) означает вывод данных на устройство, чтение данных из регистра – ввод с устройства.
· Регистр управления и состояния содержит два типа двоичных разрядов (битов). Биты состояния служат для передачи процессору информации о текущем состоянии устройства (например, флагов готовности и ошибки, сигналов прерывания). Биты управления служат для передачи на устройство команд, позволяющих задать выполняемую операцию, запустить выполнение операции, установить режимы работы устройства и т.п.
В различных компьютерах используется один из двух способов адресации регистров устройств.
· Отображение регистров устройств на память. При этом способе для устройств отводится определенная часть адресного пространства памяти, а для работы с устройствами можно использовать те же команды, что и для работы с основной памятью (например, команду MOV).
· Адресация регистров через порты ввода/вывода. Для портов отводится отдельное адресное пространство, и для работы с ними имеются специальные команды (например, IN и OUT).
Первый способ удобнее для программирования, поскольку позволяет использовать более широкий набор команд. Однако этот способ труднее реализовать на аппаратном уровне, поскольку аппаратура должна определять, относится ли конкретный адрес к памяти или к устройству, и по-разному обрабатывать эти два случая.
Среди различных возможных конфигураций однопроцессорной вычислительной системы принято выделять два основных типа: системы с магистральной и с радиальной архитектурой (рис. 2‑1).
Рис. 2‑1
· Магистральная архитектура основана на подключении всех имеющихся устройств, включая процессор и память, к единой системной магистрали (шине), которая объединяет в себе линии передачи данных, адресов и управляющих сигналов. Совместное использование магистрали различными устройствами подчиняется специальным правилам (протоколу), обеспечивающему корректность работы магистрали.
· Радиальная архитектура предполагает, что каждое из устройств, включая память, подключается к процессору отдельно, независимо от других устройств, и взаимодействует с процессором по собственным правилам.
Для программиста понятия магистральной и радиальной архитектуры имеют несколько иное содержание, чем для инженера-системотехника. С точки зрения программной архитектуры, неважно, подсоединено ли устройство к процессору напрямую или через посредство системной магистрали. Важно то, какие сигналы должна посылать и принимать программа, работающая с устройством, и какие команды могут для этого использоваться.
Основная особенность магистральной архитектуры – единообразный способ подключения всех устройств. Структура регистров устройства стандартизуется, при этом определяется, какими сигналами любое устройство может обмениваться с процессором и каким разрядам регистра должны соответствовать эти сигналы. Конечно, не всякое устройство нуждается в использовании всего набора стандартных сигналов. Некоторые типы устройств могут, например, не генерировать прерываний, не сообщать об ошибках. Но те сигналы, которые устройство использует, должны соответствовать стандарту данной магистрали.
Преимуществом магистральной архитектуры является простота подключения новых типов устройств, поэтому такая архитектура особенно удобна для открытых вычислительных систем, т.е. таких, которые рассчитаны на расширяемый набор периферийных устройств.
Напротив, для радиальной архитектуры характерен индивидуальный выбор способа подключения, наиболее удобного для каждого типа устройств. При этом в принципе можно достичь экономии аппаратных ресурсов и более высокой эффективности. Случается даже, что в одном порту объединяются управляющие сигналы от нескольких разных устройств. Очевидно, подобная архитектура удобна только в том случае, когда она рассчитана на постоянный набор устройств. Расширение радиальной системы всегда вызывает затруднения.
Исходя их этих определений, не так уж легко точно охарактеризовать современные IBM-совместимые ПК. Исходная модель IBM PC имела довольно четко выраженную радиальную архитектуру и небольшой набор стандартных устройств. В последующих моделях были сделаны значительные шаги по стандартизации подключения новых устройств. Однако и сегодня эти компьютеры не тянут на магистральную архитектуру в полном смысле слова: у них для этого слишком много разных шин.
Важной деталью архитектуры современных компьютеров является такое устройство, как контроллер прямого доступа к памяти (ПДП, англ. DMA – Direct Memory Access). Если обычно весь обмен данными идет через регистры процессора, то ПДП подразумевает прямой перенос данных с устройства в память или обратно. Роль процессора в данном случае только в том, чтобы инициировать операцию ввода/вывода блока данных, послав соответствующие команды контроллеру ПДП. Далее процессор не участвует в выполнении обмена данными. Завершив операцию, контроллер ПДП посылает сигнал прерывания, извещая об этом процессор. Это позволяет повысить производительность системы за счет частичной разгрузки процессора и магистрали.
2.5. Способы организации ввода/вывода
2.5.1. Ввод/вывод по опросу и по прерываниям
Рассмотрим более подробно работу программы, непосредственно выполняющей ввод или вывод данных на конкретное устройство. (На самом деле, этой работой обычно занимается драйвер устройства, так что мы фактически рассматриваем логику работы драйвера.)
Для определенности положим, что программа должна выдать N байт данных из массива A на символьное устройство X. Для операции ввода могут использоваться те же подходы, которые будут рассмотрены здесь для операции вывода.
Пусть архитектура устройства представлена регистром данных X.DATA и флагом готовности X.READY. Когда X.READY = TRUE, в регистр X.DATA можно выдавать очередной байт данных. Запишем на псевдокоде, близком к языку Паскаль, варианты организации соответствующей программы.
а) Ввод/вывод без проверки готовности
i := 1;
while i <= N do begin
X.DATA := A[i];
i := i + 1;
end;
Этот «наглый» способ вывода вполне работоспособен, если используется «всегда готовое» устройство (например, монитор), т.е. флаг X.READY всегда истинен и потому вообще не нужен. При попытке использовать тот же подход для вывода на принтер мы убедились бы, что напечатаны будут лишь некоторые символы, которым посчастливилось быть выданными в редкие моменты готовности принтера.
б) Ввод/вывод по опросу готовности
i := 1;
while i <= N do begin
while not X.READY do
;
X.DATA := A[i];
i := i + 1;
end;
Здесь добавлен цикл ожидания, в котором не делается ничего, кроме постоянной циклической проверки готовности устройства. Передача данных происходит только тогда, когда устройство готово. Поскольку после выдачи одного байта устройство вполне может опять перейти в состояние неготовности, следует опять выполнять цикл ожидания, пока выданный символ не будет обработан устройством.
Такая организация ввода/вывода позволяет корректно работать с любыми устройствами. Этот способ действительно применяется в некоторых однозадачных системах. Недостатком данного способа является непроизводительная трата времени на постоянное «долбление» флага готовности. При современном соотношении скоростей работы процессора и периферии, цикл ожидания может повторяться миллионы раз перед выдачей каждого байта. Более того, если по каким-то причинам устройство вообще не перейдет в состояние готовности, то работа всей системы может быть парализована бесконечным циклом ожидания.
в) Ввод/вывод по прерываниям
i := 1;
while i <= N do begin
X_INT: if not X.READY
return;
X.DATA := A[i];
i := i + 1;
end;
Здесь исчез цикл ожидания, вместо него – однократная проверка готовности и оператор возврата, если не готово.
Куда, собственно, происходит возврат? Чтобы это понять, надо вспомнить, что данный фрагмент – явно не единственная программа, работающая в данный момент на ЭВМ. Очевидно, операция вывода была начата операционной системой по запросу какой-то программы. Данный фрагмент был вызван как подпрограмма ОС, и возврат означает передачу управления ОС. Как система распорядится полученным временем? Это уже совсем другой вопрос, не связанный с вводом/выводом. Например, ОС может переключиться на другой процесс. Или, от нечего делать, запустить экранную заставку либо программу самотестирования.
Но как же быть с брошенной на полпути операцией вывода? Для ее возобновления будет использовано аппаратное прерывание, которое должно выдать устройство X при переходе в состояние готовности. Системный обработчик прерывания должен будет передать управление по адресу, обозначенному меткой X_INT. После нелишней дополнительной проверки готовности программа вывода передаст очередной байт на устройство, затем снова проверит готовность и, возможно, вновь вернет управление системе. Таким образом, выполнение ввода/вывода разбивается на отдельные интервалы работы при готовности устройства, перемежающиеся работой системы, пока устройство не готово.
Для устройств, использующих контроллер ПДП, возможные варианты организации работы остаются, по сути, теми же, но только используются гораздо более крупные операции: вместо ввода или вывода одного элемента данных выполняется ввод/вывод целого блока данных, и только после этого контроллер переходит в состояние готовности и генерирует прерывание.
Дата добавления: 2015-09-07; просмотров: 1061;