- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания Использование NuMega DriverStudio для написания WDM-драйверов - Александр Тарво
Шрифт:
Интервал:
Закладка:
KIoRange m_range;
…
KIoRegister m_reg = m_range[6];
…
Применение KIoRegister упрощет процесс программирования и улучшает читабельность программы.
• KMemoryRange используется для отображения диапазона адресов памяти из адресного пространства шины в адресное пространство процессора (адресное пространство системы). После того, как память будет отображена, драйвер должен использовать методы доступа к памяти, позволяющие оперировать 8, 16 и 32– битными значениями.
• KMemoryRegister аналогичен KIoRegister, за исключением того, что в данном случае он представляет из себя отдельную ячейку памяти в адресном пространстве устройства.
• KMemoryToProcessMap используется для отображения диапазона адресов памяти шины в адресное пространство пользовательского процесса. Это может оказаться очень удобным: пользователь может напрямую общаться с памятью устроства в программе, как с обычным буфером. Впрочем, такое отображение следует применять с большой осторожностью: возможна ситуация, когда пользователь запустит несколько экземпляров программы, и все они начнут работать с памятью устройства одновременно. Вряд ли стоит объяснять, к чему это может привести.
Стоит отметить, что немалая часть устройств могут общаються со своей памятью только словами. Длина слова зависит от устройства, и может колебаться в широких пределах. Обычно для PCI-устройств — 32 бит.
В документации настоятельно рекомендуется использовать только эти классы для управления оборудованием. Это связано с возможной переносимостью драйвера на другие платформы. При использовании этих классов, которые, в свою очередь, используют функции DDK для доступа к оборудованию, процесс портирования пройдет безболезненно, т.к. для доступа к устройству будет использован HAL. Если же программист будет пытаться управлять устройствами самостоятельно, то драйвер придется переписывать при переносе на другую платформу.
Есть еще одна причина, по которой стоит использовать эти классы: ведь с ними разрабатывать драйвер намного проще!
Объекты синхронизацииКак и все Windows–программы, драйвера являются частью многозадачной операционной системы, в которой выполняется множество процессов и потоков. Драйвер, как и программа, также может содержать несколько потоков. При этом, естественно, возникает проблема синхронизации работы этих потоков, совместного доступа к данным и т.п. Особенно актуальной эта проблема становится в многопроцессорной системе. Windows 2000 предназначается для работы в многопроцессорных системах, и если пренебречь синхронизацией при разработке драйвера, то это может повлечь за собой неприятные последствия.
Для решения задач синхронизации WDM (и, соответственно, DriverWorks) предлагает различные средства. Простейшим из объектов синхронизации является защелка (Spin Lock), представленная классом KSpinLock. Принцип действия защелки очень прост: чтобы запретить любому другому потоку в системе доступ к данным, нужно вызывать метод Lock защелки. Любой поток, пытающийся получить доступ к заблокированным данным, уснет. Чтобы снять блокировку, нужно вызвать метод Unlock.
Класс диспетчера KDispatcherObject является суперклассом для нескольких важных классов синхронизации. Эти классы управляют планировщиком Windows и позволяют синхронизировать как работу драйверов, так и работу приложения пользователя и драйвера. Все классы, порожденные от KDispatcherObject, имеют два важных отличия:
• С объектом диспетчера связана логическая переменная–флажок, который может находиться в двух состояниях: сигнализировать (TRUE) и молчать (FALSE).
• Если поток вызовет метод Wait диспетчера, он приостановится до тех пор, пока диспетчер не перейдет в состояние "сигнализирует".
При работе с объектами диспетчера и его подклассов следует иметь в виду, что нельзя блокировать поток при обработке прерывания. Последствия будут фатальными.
Подклассы класса KDispatcherObject:
KEvent — используется для синхронизации работы потоков. Kevent почти не отличается от объекта диспетчера.
KSemaphore инкапсулирует системный объект семафора. Семафор отличается от объекта события тем, что имеет счетчик. Семафор сигнализирует в том случае, если счетчик больше нуля. Семафоры могут быть полезны, например, при управлении несколькими пото– ками.
KTimer — таймер. При создании таймера его флажок находится в состоянии "молчит". Временной интервал таймера задается функцией Set с точностью до 100 нс. На практике таймер устойчиво работает с временем ожидания >= 10 мс. Когда пройдет указанный промежуток времени, таймер перейдет в состояние "сигнализирует". Подклассом Ktimer является класс KTimedCallBack. В нем по истечении промежутка времени выполняется вызов отложенной процедуры (DPC).
KSystemThread позволяет создать новый поток в драйвере. Потоки в драйвере используются в разных целях. В основном это — поллинг медленных устройств и работа на многопроцессорных системах. Для запуска потока следует создать функцию, которая станет функцией потока и вызвать метод Start. Для уничтожения потока — метод Terminate. При работе с потоками можно использовать все упомянутые выше классы синхронизации.
Дополнительные классы.DriverWorks предоставляет дополнительные классы для нужд программиста. Это классы очередей, списков, стеков; классы файлов и Unicode–строк; классы синхронизации.
Списки представлены класами KList, KInterlockedList, KInterruptSafeList. Они представляют шаблоны двунаправленных списков и стандартные методы для вставки, удаления и добавления элементов. Различаются эти классы методами синхронизации. KList не содержит никаких методов синхронизации и защиты данных. KInterLockedList использует защелки (spin locks) для защиты внутренних связей в списке. KInterruptSafeList использует присоединенный объект прерывания для защиты связей. По аналогичному принципу работают шаблоны классов FIFO (стек): KFifo, KLockableFifo, KInterruptSafeFifo. Класс KFile инкапсулирует методы для работы с файлами. Этот класс позволяет читать и записывать данные в файл а также изменять атрибуты файлов. Для представления Unicode – строк используется класс KUstring. Методы данного класса позволяют выполнять сравнение, конкатенацию, доступ к символам строки и разнообразные преобразования типа.
Связь драйвера с приложением пользователяТакже остается неясным еще один вопрос, связанный с драйверами: как именно с нашим объектом устройства может связаться приложение или другой драйвер? Большинство из устройств в системе именованы, хотя теоретически допускается существование неименованных (anonymous) устройств. Связь с устройством можно установить двумя методами:
• при помощи GUID.
• при помощи символической ссылки.
1. GUID (Globally Unique Identifier, глобально уникальный идентификатор) — 16-байтное уникальное число. GUID используются для идентификации в системе драйверов, СОМ-объектов и т.п. В идеале, во всем мире не может быть двух одинаковых GUID, поэтому GUID может быть абсолютно уникальным идентификатором драйвера. GUID генерируется на основе текущей даты, времени и номера сетевого адаптера, если такой присутствует, и обычно указывается в заголовочном файле класса устройства и программы, которая хочет связаться с ним приблизительно таким образом:
#define MyDevice_CLASS_GUID
{ 0xff779f4c, 0x8b57, 0x4a65, { 0x85, 0xc4, 0xc8, 0xad, 0x7a, 0x56, 0x64, 0xa6 } }
2. Символическая ссылка (symbloic link) похожа на путь к файлу и в тексте программы имеет вид:
char *sLinkName = "\\.\MyDevice";
Если отбросить лишние символы бэкслэша, необходимые для соблюдения синтаксиса С++, то символическая ссылка оказывается строкой \.MyDevice. Чтобы понять принцип работы символической ссылки, следует знать, что в ОС есть системный каталог различных объектов, которые присутствуют в системе: драйверов, устройств, объектов событий, семафоров и т.п. Символическая ссылка – специфический тип объекта, который обеспечивает доступ к другим системным объектам. Специальный подкаталог системного каталога зарезервирован для символических ссылок на другие объекты ОС. Программа пользователя может обратиться к этим символическим ссылкам при помощи функций API.
Как же следует проектировать интерфейс с драйвером? Следует использовать GUID или символическую ссылку?
Идентификация драйвера при помощи GUID считается более правильной. Как было упомянуто выше, специальные алгоритмы гарантируют то, что GUID будет действительно уникальным. А кто мешает разработчику, находящемуся на другом конце света, также создать устройство с той же ссылкой на него \.MyDevice? Вообще-то, никто. Но с другой стороны, с написанной на понятном английском языке ссылкой гораздо проще обращаться, особенно на этапе разработки драйвера, чем с длинным и непонятным GUID. Так что, вероятно, на этапе разработки и отладки драйвера для интерфейса драйвера с приложением лучше использовать символическую ссылку, а для коммерческой версии драйвера — GUID.