- •Введение 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-файла
- •Приложение б Графические материалы
2.3.3 Обработка расширенных запросов ioctl
Если присмотреться к различным типам запросов, поступающим устройству, окажется, что большинство из них связано с чтением или записью данных. Тем не менее, время от времени у приложений возникает необходимость во «внеочередном» взаимодействии с драйвером. Для большинства типов устройств приложения могут использовать стандартную функцию Microsoft Win32 API DeviceIoControl. На стороне драйвера вызов DeviceIoControl в приложении преобразуется в пакет запроса ввода/вывода (IRP) с основным кодом функции IRP_MJ_DEVICE_CONTROL [2.2].
Для управления сами устройством диспетчер ввода/вывода посылает драйверу пакет с кодом управления вводом/выводом (IOCTL). Какие именно коды управления будет посылаться зависит от типа устройства [2.2]. О том, какие коды должен обязательно поддерживать функциональный USB драйвер точно ничего не сказано. Поэтому приведенный далее список кодов управления был получен эмпирическим путем. Также для упрощения разработки, я решил разместить все определения IOCTL в отдельном заголовочном файле – DACAL_IOCTL.h.
Список кодов управления:
#ifndef DACAL_IOCTL_H
#define DACAL_IOCTL_H
#define USB_IOCTL_INDEX 0x0000
#define IOCTL_USB_GET_CONFIG_DESCRIPTOR CTL_CODE(FILE_DEVICE_UNKNOWN,\
USB_IOCTL_INDEX,\
METHOD_BUFFERED, \
FILE_ANY_ACCESS)
#define IOCTL_USB_RESET_DEVICE CTL_CODE(FILE_DEVICE_UNKNOWN, \
USB_IOCTL_INDEX+1,\
METHOD_BUFFERED, \
FILE_ANY_ACCESS)
#define IOCTL_USB_RESET_PIPE CTL_CODE(FILE_DEVICE_UNKNOWN, \
USB_IOCTL_INDEX+2,\
METHOD_BUFFERED, \
FILE_ANY_ACCESS)
#define IOCTL_USB_STOP_STREAM CTL_CODE(FILE_DEVICE_UNKNOWN, \
USB_IOCTL_INDEX+3,\
METHOD_BUFFERED, \
FILE_ANY_ACCESS)
#define IOCTL_USB_START_STREAM CTL_CODE(FILE_DEVICE_UNKNOWN, \
USB_IOCTL_INDEX+4,\
METHOD_BUFFERED, \
FILE_ANY_ACCESS)
#endif
2.3.4 Поддержка запросов Plug and Play
Plug and Play Manager передает информацию и запросы драйверам устройств посредством пакетов запросов ввода/вывода (IRP) с основным кодом функции IRP_MJ_PNP. Что примечательно, так это то, что в предыдущих версиях Windows NT драйверы устройств были обязаны выполнять большую часть работы по обнаружению и настройке своих устройств. К счастью, драйверы WDM могут поручить эту работу PnP Manager [2.2].
Запросам Plug and Play в модели WDM отведены две роли. В своей первой роли эти запросы указывают драйверу, когда и как он должен изменять конфигурацию самого себя или устройства. Существует три обязательных запроса, которые должен обрабатывать наш драйвер [2.3].
PnP Manager при помощи запроса IRP_MN_ START_DEVICE сообщает функциональному драйверу, какие ресурсы ввода/вывода были выделены устройству, а также приказывает функциональному драйверу выполнить всю необходимую настройку аппаратной и программной части для нормального функционирования устройства. IRP_MN_STOP_DEVICE приказывает функциональному драйверу отключить устройство. IRP_MN_REMOVE_DEVICE приказывает функциональному драйверу отключить устройство и освободить связанный с ним объект устройства.
Кроме того, запросам PnP отводится и другая, более сложная роль — они управляют драйвером в процессе смены состояний, показанных на рисунке 2.5 [2.2]. Основные состояния устройства — WORKING и STOPPED. Состояние STOPPED является исходным состоянием устройства непосредственно после создания объекта устройства. Состояние WORKING означает, что устройство полностью работоспособно. Два промежуточных состояния — PENDINGSTOP и PENDINGREMOVE — возникают из-за запросов, которые должны быть обработаны всеми драйверами устройства перед выходом из состояния WORKING. Состояние SURPRISEREMOVED возникает при непредвиденном удалении физического оборудования из системы.
Рисунок 2.5 – Диаграмма состояний устройства