- •Введение 5
- •1 Исследовательский раздел
- •1.1 Анализ существующих аналогичных систем
- •1.1.1 Обзор архитектуры устройств usb
- •1.2 Обоснование выбора программно-аппаратных средств
- •1.3 Постановка задачи
- •1.4 Развернутое техническое задание
- •1.4.1 Общие сведения
- •2.1.1 Основные дескрипторы usb драйвера
- •2.1.1.1 Дескриптор устройства
- •2.1.1.2 Дескриптор расширения устройства
- •2.1.1.3 Дескриптор конфигурации
- •2.1.1.4 Дескриптор интерфейса
- •2.1.1.5 Дескриптор конечной точки
- •2.2 Разработка функциональной схемы драйвера
- •2.2.1 Драйвер в иерархии wdm
- •2.2.2 Уровни обмена данными usb устройств
- •2.2.3 Архитектура системного драйвера usb
- •2.2.4 Основные рабочие процедуры драйвера
- •2.2.5 Управление перемещаемостью кода в драйвере
- •2.3 Разработка алгоритмического обеспечения
- •2.3.1 Инициализация драйвера
- •2.3.3 Обработка расширенных запросов ioctl
- •2.3.4 Поддержка запросов Plug and Play
- •2.3.5 Управление питанием
- •2.3.5.1 Обработка запросов irp_mj_power
- •2.3.6 Процедура деинициализации драйвера
- •2.4 Разработка программного обеспечения
- •2.4.1 Процедура DriverEntry
- •2.4.2 Процедура DriverUnload
- •2.4.3 Процедура AddDevice
- •2.4.4 Процедура передачи запроса usbd
- •2.4.5 Обработчики usbCreate и usbClose
- •2.4.6 Обработчик ConfigureDevice
- •2.4.7 Обработчики запросов на чтение и запись
- •3 Технологический раздел
- •3.1 Технология разработки драйверов для операционных систем семейства Windows
- •3.1.1 Архитектура Windows Driver Model
- •3.1.2 Выбор типа разрабатываемого драйвера
- •3.1.3 Разработка usb драйвера
- •3.2 Технология отладки драйверов в операционных системах семейства Windows
- •3.2.1 Основные отладочные тесты
- •3.2.2 Основные «проблемы», возникающие при отладке драйвера
- •3.2.2.1 Аппаратные проблемы
- •3.2.2.2 Программные проблемы
- •3.2.3 Основные отладчики и утилиты для проверки драйвера
- •3.2.3.1 Отладчик WinDbg
- •3.2.3.2 Driver Verifier
- •3.2.4 Общие приемы отладки драйвера
- •3.2.4.1 Установка фиксированных точек прерывания
- •3.2.4.2 Промежуточный вывод на экран
- •3.2.4.3 Сохранение отладочного кода в исходном тексте драйвера
- •3.2.4.4 Перехват некорректных условий
- •3.2.4.5 Обнаружение утечек памяти
- •3.2.5 Замечания по отладке драйверов
- •4 Безопасность жизнедеятельности
- •4.1 Анализ эргономических параметров рабочего места пользователя пэвм
- •4.1.1 Общие эргономические аспекты рабочего места
- •4.2 Организация рабочего места пользователя с учётом эргономических требований
- •4.2.1 Организация рабочего стола
- •4.2.2 Рабочее кресло
- •4.2.3 Работа с клавиатурой и мышью
- •4.2.4 Расположение и эргономические характеристики монитора
- •4.2.5 Внутренний объем
- •4.2.6 Рабочая поза пользователя пэвм
- •4.3 Экологическая оценка и переработка узлов компьютерной техники содержащих платину
- •4.3.1 Извлечение платины из отработанных катализаторов
- •4.3.2 Извлечение платины из радиооборудования и сплавов для электрических контактов
- •5 Экономический раздел
- •5.1 Планирование разработки драйвера с построением графика выполнения работ
- •5.1.1 Определение этапов и работ по созданию программного продукта
- •5.1.2 Расчет трудоемкости и продолжительности работ
- •5.1.3 Построение графика выполнения работ
- •5.2 Расчет затрат на разработку
- •5.3 Оценка экономической эффективности проекта
- •1 К исследовательскому разделу
- •2 К специальному разделу
- •3 К технологическому разделу
- •4 К разделу «Безопасность Жизнедеятельности»
- •5 К экономическому разделу
- •Приложение а Установка драйвера с помощью inf-файла
- •Приложение б Графические материалы
3.2.4 Общие приемы отладки драйвера
Зачастую проблемы исправления ошибок можно легко устранить при наличии достаточного объема диагностических сообщений. Ниже приводятся приемы, основанные как раз на этом.
3.2.4.1 Установка фиксированных точек прерывания
При использовании интерактивных отладчиков найдется не так много причин устанавливать фиксированные точки прерывания внутри кода драйвера. Тем не менее, это можно сделать, если воспользоваться двумя функциями [3.5]:
VOID DbgBreakPoint();
VOID KdBreakPoint();
Вызов KdBreakPoint представляет из себя макроопределение, которое определяет условную компиляцию с целью выполнить вызов DbgBreakPoint. Это макроопределение не выполняет данного вызова, если выполнена релизная (без отладочных инструкций) сборка драйвера. Windows дает фатальный сбой с сообщением КМОDE_EXCEPTION_NOT_HANDLED в том случае, если драйвер применил фиксированную точку прерывания (через упомянутые вызовы), но в этот момент клиент отладки был недоступен. Если драйвер добрался до такой точки прерывания, и не оказалось отладчика то драйвер «виснет». В некоторых случаях, ситуация может быть выправлена запуском отладчика на хост-компьютере [3.5].
3.2.4.2 Промежуточный вывод на экран
Делать сообщения из недр отлаживаемого кода при помощи функций печати (вывода на экран) — это метод с давними и славными традициями. Его иногда называют «генерацией промежуточного вывода». Фактически, нет таких ошибок, которые нельзя было бы найти, если применить такой метод в достаточном объеме.
И хотя данный метод не так ныне распространен, как отладка с использованием точек прерывания в интерактивных отладчиках, тем не менее, он может быть очень полезен при поисках сбоев, связанных с временными затруднениями драйвера (например, ошибках или сбоях в последовательности событий, связанных с устройством). Для генерации промежуточных сообщений используются две функции − DbgPrint и KdPrint [3.5]. Обе функции посылают форматированные строки, созданные на целевом компьютере, отладчику WinDbg, работающему на хост-компьютере.
Вызов KdPrint на самом деле является макроопределением и превращается в пустышку (невыполняемый участок) в релизной сборке драйвера (free build).
3.2.4.3 Сохранение отладочного кода в исходном тексте драйвера
Хорошим приемом в деле доводки драйвера является сохранение отладочных фрагментов кода на их месте, даже если для потребителя была собрана релизная версия (версия без отладочных инструкций). Все это несложно сделать при помощи директив условной компиляции, и при возврате к выявлению более глубоких ошибок и повторному тестированию этот прием окажет отличную поддержку.
Утилита BUILD использует символ времени компиляции DBG, который может быть использован при составлении условно компилируемых фрагментов. В отладочной версии этому символу присвоено значение 1, в релизной версии значение DBG равно 0. При внесении отладочного кода в драйвер следует ограничивать его рамками директив условной компиляции типа #if DGB и #endif [3.5].
3.2.4.4 Перехват некорректных условий
Разработчик драйвера, как и всякий разработчик, создает свой продукт, отталкиваясь от некоторых изначальных допущений. Важно лишь, чтобы они не были беспочвенными или чрезмерно оптимистическими. В том случае, если возникают некоторые сомнения в условиях работы некоторых важных участков кода драйвера, лучше подстраховаться. Например, предполагая, что некий фрагмент кода, будет вызван только на определенном уровне IRQL, автор закладывает потенциальную возможность будущих сбоев (если данные ожидания не будут оправданы) [3.5].
Для того чтобы перехватить эти непредусмотренные отклонения, следует применять несложный прием: такие допущения должны проверяться во время выполнения, хотя бы в отладочной сборке драйвера. Макроопределения ASSERT и ASSERTMSG помогут решить эту задачу:
ASSERT( Expression );
ASSERTMSG( Message, Expression );
В случае если выражение Expression, рассмотренное как логическое, будет равно FALSE, макроопределение ASSERT произведет запись сообщения в командное окно WinDbg, подключенного на хост-компьютере для проведения отладки. Это сообщение содержит исходный код выражения, значение которого оказалось равным FALSE, имя файла (в котором был исходный текст данного фрагмента) и номер строки, где было вызвано макроопределение ASSERT. Затем предлагается сделать выбор, сделать ли прерывание в месте данного макроопределения ASSERT, игнорируя причину остановки, либо прервать процесс или поток, в котором «сработал» ASSERT (что, впрочем, совершенно аналогично применению ASSERT в Visual Studio).
Макроопределение ASSERTMSG демонстрирует точно такое же поведение, с той лишь разницей, что в сообщение включается содержимое Message (являющееся строкой) [3.5].
Следует также обратить внимание на то, что оба макроопределения используют условную компиляцию. Следовательно, совершенно недопустимо помещать какой-либо исполняемый код внутрь этих макроопределений.
Кроме того, в основе упомянутых выше макроопределений лежит использование функции RtlAssert, которая во релизных (т.е. не отладочных) версиях Windows превращается в пустышку. Следовательно, чтобы наблюдать последствия ошибок в макроопределениях ASSERT и ASSERTMSG следует тестировать драйвер под отладочной версией Windows [3.5].