Файл: 12. Управление внешними устройствами.pdf

Добавлен: 20.10.2018

Просмотров: 928

Скачиваний: 5

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

8.  Драйвер  проверяет  код  завершения  операции  и  в  зависимости  от  его 

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

данных,  либо  передает  на  верхний  уровень  сообщение  о  возникшей 

ошибке. 

Эта общая схема требует уточнения для конкретных операций. Например, 

вывод  на  принтер  по  одному  элементу  данных  неэффективен,  поэтому  в 

схему добавляются следующие шаги: 

 

стандартная  программа  печати  накапливает  группу  выводимых 

элементов  данных  в  промежуточном  буфере  вывода  и  передает  адрес 

этого буфера драйверу принтера; 

 

драйвер  принтера  запускает  процесс  печати  и  блокируется  на  время 

выполнения  операции  вывода  этой  порции  данных  (шаги  1-6 

приведенного выше алгоритма); 

 

когда принтер закончит печать заданной порции данных, он генерирует 

прерывание  (механизм  прерываний  рассматривается  ниже),  по 

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

завершающую работу (шаги 7 и 8). 

Необходимо  помнить,  что  драйвер  –  это  программа,  для  выполнения 

которой  ей  необходимо  предоставить  процессор,  а  поскольку  большинство 

операций 

ввода/вывода 

выполняется 

относительно 

медленно, 

то 

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

ввода/вывода вполне оправданно. 

Большинство драйверов имеют следующую типовую структуру: 

 

секция  запуска  предназначена  для  инициирования  операции 

ввода/вывода; 

 

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

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

соответствующей  компоненты  секции  продолжения;  часто  драйверы 

содержат несколько секций продолжения; 

 

секция завершения выполняет необходимые завершающие действия. 


background image

Одним  из  фундаментальных  понятий  подсистемы  ввода/вывода  является 

понятие 

прерывания, 

важность 

которого 

для 

функционирования 

вычислительных  систем  настолько  высока,  что  требует  отдельного 

рассмотрения. 

Прерывание  (interrupt)  –  это  механизм,  с  помощью  которого 

вычислительная система может реагировать на возникающие в ней события. 

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

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

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

прерывания.  Важнейшая  особенность  прерываний  –  непредсказуемость 

моментов их возникновения.  

Основной  тип  прерываний  –  это  внешние  или  аппаратные  прерывания, 

источниками  которых  являются  контроллеры  различных  устройств,  в  том 

числе  -  устройств  ввода/вывода.  Примерами  таких  прерываний  являются: 

нажатие  клавиши  на  клавиатуре,  нажатие  кнопки  мыши,  завершение 

дисковой  операции,  сигнал  от  системного  таймера  и  т.д.  Именно  эти 

прерывания  позволяют  организовать  согласованную  работу  всех  устройств 

вычислительной системы.  

Интуитивно  понятно,  что  возникающие  в  системе  события  могут  иметь 

разную  степень  важности,  поэтому  механизм  прерываний  реализует 

приоритетную  схему  обработки.  Все  прерывания  упорядочены  по  степени 

убывания важности следующим образом: 

 

критические сбои аппаратуры (сбой питания, ошибка шины); 

 

прерывания от системного таймера (основа механизма квантования при 

вытесняющей многозадачности); 

 

прерывания от дисковых устройств; 

 

прерывания от сетевых устройств; 

 

прерывания от клавиатуры и мыши. 

Эти  приоритеты  играют  большую  роль  в  алгоритме  обработки 

прерываний.  Необходимо  отметить,  что  обработка  прерываний  в 


background image

существенной  степени  выполняется  на  аппаратном  уровне,  что  объясняется 

большой  частотой  их  возникновения  и  необходимостью  обработки  с 

максимально  высокой  скоростью.  Для  этого  многие  современные 

вычислительные  системы  имеют  специальное  устройство  –  контроллер 

прерываний. Каждое устройство получает свой  номер прерывания (иногда 

один  и  тот  же  номер  могут  иметь  сразу  несколько  устройств).  Когда 

устройство хочет сообщить о некотором событии, оно выставляет сигнал на 

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

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

следующие действия: 

 

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

новое  прерывание  игнорируется,  не  обрабатывается,  но  устройство 

− 

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

шине до наступления “лучших времен”, т.е. освобождения процессора; 

 

если  процессор  выполняет  менее  приоритетную  работу,  эта  работа 

прерывается  с  сохранением  контекста  и  происходит  переключение  на 

обработку нового прерывания. 

Простейший  способ  запуска  обработчиков  прерываний  состоит  в 

использовании  специальных  таблиц,  называемых  таблицами  векторов 

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

памяти  соответствующих  обработчиков  прерываний.  Сама  таблица 

находится в памяти в строго фиксированном месте и индексируется номером 

прерывания.  Например,  если  прерывания  перенумерованы  от  0  до  255,  то 

таблица содержит 256 записей по 4 байта, т.е. занимает 1 Кб памяти. В этом 

случае по номеру прерывания (индекс в таблице!) сразу определяется адрес 

той команды, с которой начинается код соответствующего обработчика. Этот 

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

выполнение  кода  обработчика.  Само  переключение  контекста  выполняется 

обычным образом, с сохранением информации о прерванном потоке и с его 

возобновлением, когда это будет возможно. 


background image

Кроме  внешних  (аппаратных)  прерываний  часто  рассматриваются  и  два 

других  типа  прерываний  –  внутренние  и  программные.  Внутренние 

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

очередная команда в этом потоке по тем или иным причинам не может быть 

выполнена.  Например:  попытка  деления  на  ноль,  обращение  по 

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

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

(часто  их  называют  исключениями)  распознаются  процессором  и  должны 

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

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

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

функций.  Программные  прерывания  имеют  меньший  приоритет  по 

сравнению с аппаратными и поэтому обрабатываются в последнюю очередь. 

В  качестве  примера  ниже  приводятся  шестнадцатеричные  адреса 

некоторых прерываний процессоров семейства Intel. 

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

  08h - от системного таймера; 

  09h - от клавиатуры; 

  0Eh - от гибкого диска; 

  76h - от жесткого диска. 

Внутренние прерывания: 

  00h - деление на 0; 

  0lh - пошаговое выполнение команд программы в режиме отладки. 

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

  10h – обращение к подпрограммам BIOS управления видеосистемой; 

  13h – обращение к подпрограммам BIOS управления дисками; 

  16h – обращение к подпрограммам BIOS управления клавиатурой. 

Управляющие  программы,  которые  можно  назвать  одним  термином 

“диспетчер  (или  менеджер)  ввода/вывода”,  реализуют  верхний  уровень 

программного  слоя  подсистемы  ввода/вывода.  Главное,  но  не  единственное 


background image

назначение  диспетчера  –  принимать  вызовы  на  выполнение  операций 

ввода/вывода  от  прикладных  и  системных  процессов,  транслировать  эти 

вызовы  соответствующим  драйверам  и  возвращать  результаты  выполнения 

затребованных операций процессам-потребителям. Особенно актуальной эта 

задача  становится  в  условиях  многозадачности,  когда один  и  тот же  ресурс 

может потребоваться нескольким процессам.  

Для  решения  такой  задачи  диспетчер  ввода/вывода  должен  в  каждый 

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

системе  устройств.  Для  этого  система  создает  и  поддерживает  одну  или 

несколько связанных информационных структур данных (таблиц). Основная 

таблица  должна  содержать  перечень  всего  имеющегося  в  системе 

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

содержащая следующие данные: 

 

тип устройства и его основные характеристики; 

 

номера используемых портов и выделенных устройству прерываний; 

 

информация о драйвере устройства, в частности – адреса точек входа 

всех входящих в него процедур; 

 

текущее состояние устройства и, в частности, идентификатор процесса, 

использующего устройство в данный момент; 

 

если устройство использует буферы для обмена данными, то адреса 

размещения в памяти всех буферов; 

 

адрес начала списка процессов, ожидающих данное устройство; 

 

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

вызовами. 

Обобщенный  алгоритм  работы  диспетчера  ввода/вывода  можно 

представить следующим образом: 

 

диспетчер  принимает  запрос  на  выполнение  операции  в  виде 

системного  вызова  от  активного  процесса  и  проверяет  правильность 

передаваемых в этом запросе параметров;