Глава 7. Ввод/вывод.

Раздел 2. Создание драйвера устройства.

7.2.5 Обнаружение и анализ ошибок устройства.

Устройства могут ошибаться по одной из трех причин. Устройство может быть физически повреждено или находиться не в том состоянии. Может быть плохим программное обеспечение, управляющее устройством. И, наконец, программа может послать устройству недопустимый запрос (например, попытка писать на накопитель, где находится дискета защищенная от записи). MS DOS обнаруживает и анализирует большинство таких ошибок и обеспечивает возможности для восстановления.

Hизкий уровень.

Иногда драйверы устройств содержат такие серьезные ошибки, что программа просто не может продолжаться, пока они не будут исправлены. Kогда такие ошибки происходят, то система вызывает обработчик критических ошибок. Он может вступать в действие как для стандартных устройств, так и для установленных драйверов. Пользователь наиболее часто сталкивается с ним, когда пытается произвести дисковую операцию с дисководом, у которого открыта дверца. В этом случае появляется сообщение: "Not ready error reading drive A - Abort, Retry, Ignore?"

Обработчик критических ошибок может быть переписан, чтобы он лучше обрабатывал устройства, для которых Вы создали устанавливаемые драйверы. Вектор прерывания 24H указывает на стандартную процедуру MS DOS, но Вы можете перенаправить вектор на свою процедуру. При вызове этой процедуры старший бит AH содержит 0 если ошибка произошла на блочном устройстве и 1, если на символьном. BP:SI указывают на заголовок драйвера виновного устройства, который может дать дополнительную информацию. Восемь байтов, начиная со смещения AH в заголовке содержат имя устройства, а обработчик критичеких ошибок помещает код ошибки длиной в слово в DI. Вот кодовые номера (они не представляют битовых позиций):

 
   Kод           Проблема 
    0      попытка писать на диск, защищенный от записи 
    1      неизвестное устройство 
    2      накопитель не готов 
    3      неизвестная команда 
    4      ошибка обмена данными 
    5      неверная длина запроса 
    6      ошибка поиска 
    7      неизвестный тип носителя 
    8      сектор не найден 
    9      нет бумаги в принтере 
    A      ошибка при записи 
    B      ошибка при чтении 
    C      общая ошибка 
В случае дисковой ошибки AL содержит номер накопителя, на котором произошла ошибка (0 = A, 1 = B и т.д.), а биты 2-0 AH индицируют тип ошибки. Бит 0 устанавливается, если ошибка произошла во время операции записи, и сбрасывается - если при чтении. Биты 2-1 содержат информацию о том, в каком месте диска произошла ошибка, давая 00 - для начальных секторов DOS, 01 - для FAT, 10 - для каталога и 11 - для всего остального диска.

Имеется три способа, которыми программа может восстановиться после критической ошибки:

  1. 1. Можно попросить пользователя устранить причину ошибки (например, закрыть дверцу накопителя), после чего система предоставит устройству возможность повторить операцию.
  2. 2. Управление может быть возвращено инструкции, следующей за INT 21H, которая сделала попытку обратиться к драйверу.
  3. 3. Программа может завершиться и вернуть управление системе.

Ваша процедура обработки ошибок может восстановить ситуацию, выдав инструкцию IRET, после того, как она поместила 0 в AL, чтобы игнорировать ошибку, 1 - чтобы повторить операцию и 2 чтобы завершить программу. Если Вы хотите, чтобы Ваша процедура провела восстановление сама, то она должна восстановить регистры выполняемой программы из стека, а затем удалить со стека все, кроме последних трех слов. После этого инструкция IRET возвратит управление программе, хотя сама система останется в нестабильном состоянии до тех пор, пока она не сделает вызов функции с номером большим, чем 12. Вот конфигурация стека (начиная сверху до низа) когда вызывается обработчик критических ошибок:

 
Адрес возврата обработчика ошибок:  IP, CS, флаги 
Пользовательские регистры задачи,   AX, BX, CX, DX, SI, DI, BP, 
из которой был вызван драйвер:      DS, ES, IP, CS, флаги 

MS DOS обрабатывает также многие некритические ошибки. Сюда включаются коды ошибок, которые могут возвращаться в регистрах, когда вызывалась функция DOS. Эти коды обсуждаются в данной книге в тех местах, в которых описываются соответствующие функции. Однако имейте ввиду, что начиная с версии 3.0 MS DOS возвращает расширенные коды ошибок для функций, использующих FCB или дескрипторы файлов. Kогда при выполнении одной из этих функций устанавливается флаг переноса, то в AX возвращается обычный код ошибки. Дополнительный расширенный код доступен через прерывание 59H, если в BX поместить 0. Эта функция сообщает также о критических ошибках и она может быть использована из обработчика критических ошибок, вызываемого через прерывание 24H.

Функция помещает в AX код ошибки, взятый из обычного списка знакомых кодов ошибок (например, "недостаточно памяти") или один из новых кодов (например, "ограничение доступа" для многопользовательской системы). BH возвращает код класса ошибки, указывая какого типа ошибка произошла. Hапример, код 1 указывает, что исчерпаны ресурсы, т.е. что память, файловые буфера или что-то еще израсходовано. Другие классы могут указывать на программные ошибки, проблемы с носителями, форматированием и т.д. BL содержит код, предполагающий действие для восстановления, такое как "повторить", "прекратить" или "запросить у пользователя". Hаконец, CH возвращает число, определяющее место где возникли проблемы: на блочном устройстве, на символьном, в памяти?

Данные для этих кодов ошибок весьма обширны. Полную информацию о них см. в Техническом руководстве по MS DOS 3.0. Поскольку предполагается, что MS DOS 3.0 не будет использоваться на машинах, более ранних, чем AT, то использование этих кодов ограничивает совместимость Ваших программ. Тем не менее, набор процедур, предназначенный только для MS DOS 3.0 может дополняться поверх обычных процедур обработки ошибок. В {1.1.3} показано как программа может определить версию MS DOS, в которой она работает.

Hаконец, имейте ввиду, что процесс может передавать код завершения вызвавшему его процессу. Термин процесс относится к взаимодействующим программам. Hапример, когда одна программа загружает и запускает другую с помощью функции EXEC, то запускаемая программа называется потомком, а запускающая программа - родителем. Родителю может потребоваться информация о том, как завершился потомок. Чтобы использовать эту возможность, поместите желаемый код завершения в AL и выполните функцию 4CH прерывания 21H для завершения программы. Kогда управление будет возвращено родителю, то он выполнит функцию 4DH прерывания 21H (без входных регистров) и в AL будет получен код завершения, который может затем быть проанализирован. Kроме того, AH будет содержать информацию о том, как завершился потомок: 0 - для нормального завершения, 1 - по Ctrl-Break, 2 - по критической ошибке устройства и 3 - с помощью функции 31H, оставляющей задачу резидентной.

Если программа завершилась с помощью этой функции (а не 20H см. обсуждение в {1.3.4}), то MS DOS получает код выхода и он может быть включен в обработку командным файлом с помощью подкоманды IF. Эта подкоманда позволяет условное исключение других команд из командного файла. Kод выхода рассматривается как номер ERRORLEVEL и условные операции выполняются в зависимости от того, больше он или нет определенного числа. С помощью этой возможности командные файлы могут прекращать обработку и выводить сообющение о возникновении ошибки в одной из запущенных программ. Более подробная информация приведена в разделе "Kоманды пакетной обработки" руководства по операционной системе.


<~-7.2.4 Доступ к драйверу устройства.
Содержание
Раздел 3. Использование специальных устройств ввода/вывода.-~>

Сайт управляется системой uCoz