Александр Тарво - Использование NuMega DriverStudio для написания WDM-драйверов
- Название:Использование NuMega DriverStudio для написания WDM-драйверов
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Александр Тарво - Использование NuMega DriverStudio для написания WDM-драйверов краткое содержание
Использование NuMega DriverStudio для написания WDM-драйверов - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Объекты, внедренные в объект устройства, представлены в классе KDeviceQueue. Его методы не только реализуют манипуляцию с очередью, но и решают более интеллектуальные задачи. Например, есть метод, смысл которого может быть описан таким образом: "Если устройство сейчас обрабатывает запрос и занято, то помести новый запрос в очередь, иначе немедленно начни его обработку". Подобные методы сильно облегчают задачу буферизации запросов для объекта устройства. Но возможна и другая ситуация: устройство может одновременно обрабатывать запросы разного вида. К примеру, наше устройство – это дуплексный канал связи. Оно одновременно может и принимать, и передавать информацию. Если мы будем использовать для буферизации всех одну очередь, то такой подход является неэффективным. Поэтому система позволяет объектам устройств создавать дополнительные объекты очередей. Они реализованы в классе KDriverManagedQueue.
Рис. 5 — объект очереди, внедренный в объект драйвера.
Эти классы имеют методы, сходные с методами класса KDeviceQueue. Впрочем, ситуации, когда следует применять более одной очереди для буферизации запросов, встречаются не так уж и часто.
В контексте данного руководства будем считать, что прерывание (Interrupt) – асинхронный аппаратный сигнал, который обычно возникает, когда периферийному устройству необходимы ресурсы процессора. "Асинхронный" означает то, что прерывание возникает в произвольные моменты времени (если вообще возникает). Прерывание заставляет процессор прервать выполнение программы, сохранить свое состояние, обработать поступивший запрос (вызывается процедура обработки прерывания, Interrupt Service Routine, ISR) и возобновить выполнение прерванной программы. При этом останавливаются все остальные процессы и потоки ОС вне зависимости от их приоритета.
Для того, чтобы удовлетворять разнообразным требованиям, возникающим при работе разнообразных устройств и программ на различных типах компьютеров, ОС предлагает концепцию уровня запроса на прерывание (Interrupt Request Level), IRQL. Всего существует 32 IRQL для данного процессора, пронумерованных от 0 до 31. При этом 0 — самый низкий приоритет, 31 — самый высокий.
31 | Сбой работы шины |
29 | Сбой в цепи питания |
28 | Запрос от другого процессора (в многопроцессорной системе) |
Прерывания, доступные устройствам В/В | |
2 | Выполнение DPC |
1 | Исключение защиты (page fault) |
0 | Passive level |
Табл. 1 – уровни IRQL.
Для катастрофических событий ОС резервирует самые приоритетные прерывания (31–29). Для программных прерываний — прерывания с самым низким приоритетом (2–1). PassiveLevel — обычный режим работы драйвера. IRQL, предоставляемые для работы системных устройств, находятся где-то посредине нумерации уровней. О том, как эти прерывания сопрягаются с архитектурой компьютера, заботится HAL.
Естественно, в любой момент процессор может обрабатывать только один запрос на прерывание. Обработка поступившего прерывания прервется только в том случае, если поступит прерывание с более высоким приоритетом.
При проектировании процедуры обработки прерывания следует минимизировать время, которое будет затрачено на обработку прерывания. Иначе процессор будет чересчур долго обрабатывать прерывание и ни один процесс не сможет возобновить свою работу. Когда вызывается ISR первое, что она должна сделать сообщить оборудованию, что запрос на прерывание получен и обработан. После этого можно завершать обработку прерывания. Но как тогда обработать данные, поступившие от устройства, если мы сразу же завершим обработку прерывания? Для этого введен механизм вызова отложенных процедур (Deferred Procedure Call, DPC). Перед завершением работы ISR следует вызвать отложенную процедуру (DPC). DPC начнет выполнятся, как только процессор освободится от обработки прерываний. DriverWorks предоставляет класс KDeferredCall, в котором инкапсулируются данные и методы, необходимые для использования механизма DPC.
DriverWorks инкапсулирует все функции, необходимые для обработки прерываний, в классе KInterrupt. Экземпляр класса KInterrupt должен быть создан, как свойство в классе устройства. Пусть в нашем случае класс устройства называется MyDevice, объект класса KInterrupt – m_TheInterrupt. Далее в классе устройства описывается функция ISR:
BOOLEAN MyDevice::TheIsr(void);
Далее, в методе OnStartDevice следует добавить код для привязки ISR к устройству:
status = m_TheInterrupt.InitializeAndConnect(pAssignedResource,Isr,Context,0,FALSE);
где Context — значение без типа (void), передаваемое ISR.
Isr — адрес ISR, процедуры обработки прерываний.
Теперь осталось только добавить в конструктор следующий код:
VOID MyDevice::MyDevice(void) {
. . .
status = m_TheInterrupt.InitializeAndConnect(pAssignedResource, LinkTo(Isr), this, 0, FALSE );
. . .
}
Для отключения ISR следует вызвать метод Disconnect().
Естественно, данное описание не претендует быть полным описанием такой важной темы, как обработка прерываний и связанные с ней проблемы. Но в примере драйвера, описываемом ниже, отсутствует реакция на прерывания, а не упомянуть о них нельзя. Для более подробного обзора темы прерываний и DPC следует обратиться к документации DriverWorks или DDK.
Как было упомянуто выше, объект устройства управляет работой устройства при помощи специальных объектов, управляющих работой оборудования – портами В/В, прерываниями, памятью, контроллерами ПДП. Драйвер создает эти объекты для представления физических параметров устройства.
Большинство периферийных устройств находятся на шинах компьютера. В современном компьютере есть несколько шин. Обычно процессор, внешняя кэш-память, и оперативная память находятся на высокоскоростной шине, архитектура которой специфична для данного типа процессора. Шина процессора соединена мостом со стандартной скоростной шиной, на которой находятся контроллеры дисплея, некоторые скоростные устройства. Архитектура этой шины может быть процессоро-независимой. Пример такой шины — PCI. Эта шина также может быть соединена мостом со вторичной локальной шиной, часто более медленной. На ней могут находиться контроллеры дисковых накопителей, сетевых адаптеров и т.п.
Периферийные устройства обычно имеют "на борту" регистры и диапазоны адресов памяти, при помощи которых реализуется интерфейс устройства с системой. Но добраться до них не так просто: процессор ведь физически использует другие механизмы для обращения к своим "родным" портам ввода-вывода и оперативной памяти. Для того, чтобы обратится к памяти и портам устройства, находящегося на локальной шине, процессор должен выполнить отображение (mapping) адресного пространства процессора и той шины, где находится наше устройство. В результате этой операции к участку памяти, физически находящийся в устройтсве, можно обращаться, как к участку оперативной памяти процессора. При таком обращении процессор переадресует запрос локальной шине. Но тут следует вспомнить об особенностях архитектуры Windows (да и практически любой современной ОС): ведь система поддерживает механизм виртуальной памяти! Пользовательские приложения теперь работают в своем адресном пространстве, а система, в том числе и драйвера, — в своем. Куда же будет отображена память устройства?
Читать дальшеИнтервал:
Закладка: