Факультет информатики и систем управления
Кафедра ПО ЭВМ и информационные технологии
РАСЧЕТНО-ПОЯСНИТЕЛЬНАЯ ЗАПИСКА
к курсовой работе на тему:
Драйвер клавиатуры, реализующий функции музыкального синтезатора на клавиатуре для Windows NT 5
Содержание
1. Введение
2. Конструкторский раздел
2.1 Постановка задачи
2.2 Архитектура Windows NT 5
2.3 Драйверная модель WDM
2.3.1 Функции загрузки/выгрузки драйвера
2.3.2 Функции обработки запросов/прерываний
2.4 Приоритеты выполнения программного кода
2.5 Стек клавиатуры
2.6 Kernel Streaming
2.7 Описание формата MIDI-данных
2.8 Выбор структуры программного обеспечения
2.8.1 Драйвер-фильтр
2.8.2 Получение доступа к аудиоустройству
2.8.3 Взаимодействие компонент программного обеспечения
2.9 Алгоритм работы драйвера-фильтра
2.9.1 Функции загрузки/выгрузки драйвера
2.9.2 Функции обработки пакетов IRP
2.9.3 Функции работы с аудио-устройством
2.9.4 Схема хранения музыкальных параметров клавиш
2.9.5 Разделение задачи на потоки
3. Технологический раздел
3.1 Выбор средств разработки программного обеспечения
3.2 Установка драйвера в системе
3.3 Сборка программного обеспечения
3.4 Использование библиотеки DirectKS
3.5 Отправление запросов из приложения в драйвер
3.6 Описание интерфейса пользователя
3.7 Тестирование программного обеспечения
4. Заключение
5. Список литературы
6. Приложения
6.1 Функции установки драйвера в системе
6.2 Изменения в библиотеке DirectKS
1. Введение
В современных вычислительных системах важнейшую роль играет подсистема ввода/вывода. Известно, что примерно 80% инструкций программы связаны с этой подсистемой. В связи с этим в настоящее время возрастает актуальность разработки программных систем, осуществляющих взаимодействие с периферийными устройствами посредством подсистемы ввода/вывода.
Данное программное обеспечение позволяет организовать настраиваемое звуковое сопровождение нажатий клавиш на клавиатуре. Существует множество вариантов его применения, среди которых можно выделить следующие:
Упрощение работы с компьютером людям со слабым зрением.
Создание MIDI-синтезатора на клавиатуре.
Создание системы звуковой сигнализации.
В стандартную поставку ОС Microsoft Windows XP Professional входят компоненты, обеспечивающие специальные возможности операционной системы для пользователей с различными отклонениями в здоровье. Среди этих компонент следует отметить:
«Экранную клавиатуру», с помощью которой, в частности, можно озвучить выбор клавиш мышью.
Возможность озвучивания нажатий клавиш Num, Caps и Scroll Lock.
Характерной особенностью вышеперечисленных компонент является подача сигнала одной частоты независимо от нажатой клавиши и невозможность настройки параметров звучания. В этой связи представляется целесообразной разработка нового программного обеспечения, позволяющего организовать звуковое сопровождение клавиатуры в более полном объеме, в частности, настраивать выборочное озвучивание клавиш.
2. Конструкторский раздел
2.1 Постановка задачи
В соответствии с заданием на курсовую работу необходимо разработать программное обеспечение для решения следующих задач:
Вывод музыкальных нот с заданными параметрами при нажатии клавиш.
Возможность настройки пользователем параметров звучания клавиш.
Программное обеспечение состоит из двух взаимодействующих частей:
Драйвер-фильтр, реализующий первую задачу.
Программа настройки, реализующая вторую задачу.
Требования к программному обеспечению:
Драйвер-фильтр должен отслеживать нажатия всех клавиш клавиатуры PS/2 и генерировать музыкальные ноты с соответствующими клавише параметрами.
Программа настройки должна позволять пользователю редактировать параметры звучания клавиш, предоставляя удобный интерфейс.
В качестве устройства для вывода музыкальных нот используется синтезатор MIDI, встроенный в звуковую карту Sound Blaster.
Приоритетным критерием при разработке продукта является производительность для драйвера-фильтра и удобство пользователя для программы настройки.
Программное обеспечение ориентировано на работу в ОС Windows NT 5. Функционирование программного обеспечения не должно влиять на работу других драйверов системы.
2.2 Архитектура Windows NT 5
Архитектура Windows NT 5 соответствует классическим представлениям о проектировании операционных систем. Наиболее распространены реализации данной ОС для платформы Intel x86 в одно- или многопроцессорных конфигурациях, однако существуют также версии для DEC Alpha и MIPS. Windows NT 5 использует защищённый режим центрального процессора, реализует механизмы виртуальной памяти и многозадачности.
Исполняемый код в Windows NT 5 имеет два уровня привилегий: код пользовательского режима и код режима ядра. Уровень привилегий накладывает определённые ограничения: в пользовательском режиме не могут выполняться привилегированные инструкции процессора, не разрешено обращение к защищённым страницам памяти. Эти ограничения накладываются для обеспечения безопасности работы системы. Пользовательское приложение не должно иметь возможность в результате ошибки или преднамеренно вносить изменения в критические таблицы операционной системы или в память других приложений. В частности, такие ограничения запрещают пользовательскому приложению напрямую управлять внешними устройствами, потому что каждое из них является разделяемым ресурсом.
В Windows NT 5 обеспечение обмена данными и управление доступом к внешнему устройству как к разделяемому ресурсу возлагается на его драйвер. Ввод и вывод в драйверах осуществляется посредством IRP-пакетов (Input/Output Request Packet). Запросы на ввод/вывод, посылаемые приложениями или другими драйверами, обрабатываются драйвером, после чего запрашивающей программе в том же пакете посылается статус завершения операции. Общий принцип взаимодействия проиллюстрирован на рис. 2.1.
Рис.2.1. Архитектура ввода/вывода Windows NT 5
Управление внешним устройством в общем случае сводится к заполнению его регистров необходимыми данными. Монопольный доступ драйвера к этим регистрам гарантируется операционной системой. Очевидно, что при данных обстоятельствах требуется, чтобы драйвер устройства выполнялся в режиме ядра.
Обобщённая классификация драйверов Windows NT 5 может быть представлена следующим образом:
Драйверы режима ядра:
Унаследованные драйверы
Драйверы файловой системы
Видеодрайверы
Драйверы PnP (Plug And Play):
Драйверы WDM
Драйверы пользовательского режима:
Драйверы виртуальных устройств
2.3 Драйверная модель WDM
Windows Driver Model (WDM) — это стандартная спецификация Microsoft для разработчиков драйверов устройств. Она поддерживается в операционных системах Windows 98/Me/2000/XP. Компания Microsoft требует, чтобы все новые драйверы под эти операционные системы создавались по этой спецификации. Для этого от них требуется чёткое следование структуре WDM, поддержка Plug and Play и управления электропитанием.
Драйверная модель WDM построена на организации и манипулировании слоями объектов физических устройств (PDO, Physical Device Object) и объектов функциональных устройств (FDO, Functional Device Object).
Объект PDO создается для каждого физически идентифицируемого элемента аппаратуры, подключенного к шине данных, и подразумевает ответственность за низкоуровневый контроль, достаточно общий для набора функций реализуемых этим аппаратным элементом. Объект PDO – это особая структура данных, создаваемая системой для взаимодействия программного и аппаратного обеспечения.
Объекты FDO подразумевает единицу логической функциональности устройства.
Объектам FDO устройств разрешается окружать себя Объектами Фильтрами (FiDO, Filter Device objects) как показано на рис. 2.2. Соответственно, каждому FiDO объекту сопоставлен драйвер, который выполняет определенную работу. Объекты фильтры подразделяются на фильтры нижнего уровня и фильтры верхнего уровня. И тех и других может существовать произвольное количество. Они модифицируют процесс обработки запросов ввода/вывода. Объекты FDO и FiDO отличаются только в смысловом отношении. FDO объект и его драйвер считаются главными. Они обычно обеспечивают управление устройством, а объекты FiDO являются вспомогательными.
Рис. 2.2. Стек устройств
Все объекты FDO и FiDO позиционируют себя в стеке устройств. Порядок объектов в стеке определяет порядок обработки запросов ввода-вывода. Если необходимо перехватить и обработать запрос, непосредственно идущий от пользователя, то нужно устанавливать верхний фильтр. Если же нужно отслеживать обращение к портам ввода вывода, обрабатывать прерывания, то нужен нижний фильтр. Данная модель позволяет драйверу устанавливать callback процедуры. Когда запрос начинает обрабатываться, то он обрабатывается последовательно всеми драйверами стека устройства ( исключая ситуацию, когда какой-либо драйвер сам завершит обработку запроса ). После этого диспетчер ввода-вывода передает запрос callback процедуре каждого драйвера стека. Сначала запрос передается callback процедуре последнего драйвера который в стеке, потом процедуре предпоследнего драйвера и т.д. Callback процедуры нужны для того, чтобы обработать прочитанную из устройства информацию. Если фильтр обрабатывает запросы на чтение, то когда этот запрос поступит в драйвер информация еще не будет считана. Поэтому драйверу необходимо установить callback функцию. При ее вызове запрос уже будет содержать считанные данные.
Драйвер имеет следующие точки входа:
DriverEntry
DriverUnload
AddDevice
Функции для обработки пакетов IRP
ISR
2.3.1 Функции загрузки/выгрузки драйвера
WDM-драйверы отличаются от унаследованных драйверов тем, что должны содержать дополнительные точки входа для поддержки PnP. Приведем список точек входа и кратко охарактеризуем их назначение.
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject, // указатель на объект драйвера
IN PUNICODE_STRING RegistryPath) // путь к подразделу регистра,
// относящегося к драйверу
Эта функция выполняется при загрузке драйвера операционной системой. В WDM-драйверах на
DriverEntry возложены обязанности по регистрации всех остальных точек входа драйвера.
NTSTATUS
AddDevice(
IN PDRIVER_OBJECT DriverObject, // указатель на объект драйвера
IN PDEVICE_OBJECT PhysicalDeviceObject) // указатель на родительский PDO
В поддерживающих PnP драйверах через эту точку входа менеджер PnP посылает драйверу уведомление об обнаружении устройства, за которое должен отвечать драйвер. Функция
AddDevice должна создать объект устройства с помощью вызова
IoCreateDevice и при необходимости присоединить его к стеку устройств вызовом
IoAttachDeviceToDeviceStack.
NTSTATUS
DriverUnload(
IN PDRIVER_OBJECT DriverObject) // указатель на объект драйвера
Вызывается при выгрузке драйвера. В этой функции должны освобождаться все затребованные драйвером ресурсы. Драйверы WDM-модели выполняют эти действия в обработчике запросов IRP_MJ_PNP с субкодом IRP_MN_REMOVE_DEVICE, то есть при удалении устройства из системы.
2.3.2 Функции обработки запросов/прерываний
Следует выделить отдельный класс точек входа драйвера, которые предназначены для обработки IRP-пакетов с различными кодами операций. Эти точки входа регистрируются при загрузке драйвера в функции
DriverEntry. Регистрация производится путем заполнения элементов массива MajorFunction адресами диспетчеризуемых функций. Индексом в этом массиве являются коды IRP_MJ_XXX, то есть описанные числами типы пакетов IRP. Диспетчер ввода/вывода, ориентируясь на заполнение этого массива, вызывает нужные функции драйвера.
Поскольку для драйвера важны только адреса рабочих процедур, то все рабочие процедуры могут иметь совершенно произвольные имена.
Стандартный прототип таких функций обработки:
NTSTATUS
IRPControl(
IN PDEVICE_OBJECT DeviceObject, // указатель на объект устройства
IN PIRP Irp) // указатель на пакет IRP
Функции обработки пакетов IRP
Функции, адреса которых записаны в массиве MajorFunctions, вызываются диспетчером ввода/вывода для обработки соответствующих запросов от клиентского драйвера (пользовательских приложений или модулей уровня ядра). Эти запросы оформляются в виде специальных структур – IRP пакетов.
При любом запросе Диспетчер формирует IRP. Память для структуры IRP выделяется в нестраничной памяти. В IRP записывается код операции ввода вывода. Пакет IRP состоит из заголовка (рис. 2.3), который имеет постоянный размер и стека IRP (рис. 2.4). Стек имеет переменную длину.
Заголовок IRP пакета:
Поле
IoStatus типа
IO_STATUS_BLOCK содержит два подполя
Status - значение, которое устанавливает драйвер после обработки пакета.
В
Information - чаще всего число переданных или полученных байт.
Поле
AssociatedIrp.SystemBuffer типа
void* содержит указатель на системный буфер для случая если устройство поддерживает буферизованный ввод/вывод.
Поле
MdlAddress типа
PMDL содержит указатель на MDL список, если устройство поддерживает прямой ввод вывод.
Поле
UserBuffer типа
void* содержит адрес пользовательского буфера для ввода/вывода.
Поле
Cancel типа
BOOLEAN - это индикатор того, что пакет IRP должен быть аннулирован.
Рис. 2.3. Заголовок IRP-пакета
Стек IRP пакета
Основное значение ячеек стека IRP пакета состоит в том, чтобы хранить функциональный код и параметры запроса на ввод/вывод. Для запроса, который адресован драйверу самого нижнего уровня, соответствующий IRP пакет имеет только одну ячейку стека. Для запроса, который послан драйверу верхнего уровня, Диспетчер ввода/вывода создает пакет IRP с несколькими стековыми ячейками – по одной для каждого FDO.
Каждая ячейка стека IRP содержит:
MajorFunction типа
UCHAR – это код, описывающий назначение операции
MinorFunction типа
UCHAR – это код, описывающий суб-код операции
DeviceObject типа
PDEVICE_OBJECT – это указатель на объект устройства, которому был адресован данный запрос IRP
FileObject типа
PFILE_OBJECT – файловый объект для данного запроса
Диспетчер ввода/вывода использует поле
MajorFunction для того, чтобы извлечь из массива
MajorFunction нужную для обработки запроса процедуру.
Рис. 2.4 Стек IRP-пакета
Функция обработки пакетов IRP_MJ_DEVICE_CONTROL
Эта функция позволяет обрабатывать расширенные запросы от клиентов пользовательского режима. Такой запрос может быть сформирован посредством вызова функции DeviceIoControl. Каждый IOCTL запрос имеет свой код. Этот код передается как параметр функции DeviceIoControl. Код IOCTL – это 32-битное число.
Запросы IOCTL служат чаще всего для обмена данными между драйвером и приложением. Для передачи данных в Windows предусмотрены 4 способа:
METHOD_BUFFERED
Входной пользовательский буфер копируется в системный, а по окончании обработки системный копируется в в выходной пользовательский буфер.
METHOD_IN_DIRECT и METHOD_OUT_DIRECT
Необходимые страницы пользовательского буфера загружаются с диска в оперативную память и блокируются. Используются MDL-списки для доступа к буферу пользователя.
METHOD_NEITHER
При данном методе передачи не производится проверка доступности памяти, не выделяются промежуточные буфера и не создаются MDL. В пакете IRP передаются виртуальные адреса буферов в пространстве памяти инициатора запроса ввода/вывода.
Функция обработки пакетов IRP_MJ_READ
Данная функция должна обрабатывать запросы на чтение информации из устройства.
Функция обработки пакетов IRP_MJ_PNP
Данная функция должна обрабатывать запросы от менеджера PnP.