Можно ли написать приложение реального времени для ос windows
Конечная цель применения ОС РВ - сокращение сроков разработки современных аппаратно-программных комплексов реального времени. Новые системы теоретически интересны, но системные интеграторы прекрасно понимают, что новая ОС РВ должна еще успеть "обрасти" всевозможными сопутствующими инструментами, позволяющими интегрировать ее в комплексы реального времени различных конфигураций. Тем не менее, появление расширений WINDOWS NT на рынке ОС РВ не прошло незамеченным.
Соединение возможностей WINDOWS NT и требований реального времени
Повышенный интерес к использованию WINDOWS NT в СРВ налицо. Растет количество публикаций, большой интерес и в России, где уровень использования процессоров Intel в системах автоматизации выше, чем в остальном мире - это явление возникло во второй половине 80-х, когда отсутствие средств вынуждало строить управляющие системы на базе офисных IBM PC. Новые расширения РВ для WINDOWS NT часто связываются с компанией Microsoft (хотя это не так!), с ее умением подчинить себе рынок.
Однако появление WINDOWS NT реального времени интересно и с технической точки зрения – соединение возможностей этой ОС с требованиями, предъявляемыми к СРВ, открыло бы новые возможности для системных интеграторов.
Какие картины рисует себе пользователь, услышав что WINDOWS NT можно применять в системах жесткого реального времени? Естественно, полагает, что теперь он сможет:
· использовать одну и ту же ОС на всех уровнях промышленной иерархии;
· задействовать для создания приложений реального времени программный интерфейс Win32;
· применять в СРВ большое количество стандартных приложений, созданных для WINDOWS NT и, что особенно заманчиво, ее сетевые возможности.
Рассмотрим, какие способы соединения возможностей WINDOWS NT с требованиями реального времени существуют в принципе.
Есть разные способы решения этой задачи. Некоторые из них давно применяются, некоторые были использованы как раз при разработке расширений реального времени для WINDOWS NT, а кое-какие вряд ли осуществимы.
Теоретически возможны следующие подходы.
· Использование NT на верхнем уровне систем автоматизации.
· Использование этой ОС только в системах мягкого реального времени.
· Применение различных "трюков" для создания приложений жесткого реального времени в NT.
· Перенесение API-интерфейса Win32 в ОС РВ.
· Модификации ядра WINDOWS NT.
· Модификации уровня аппаратных абстракций (HAL).
· Дополнение стандартного ядра NT ядром реального времени.
Использование WINDOWS NT на "верхнем" уровне систем автоматизации
Этот метод широко распространен и часто применяется, более того, он лежит в основе одной из типовых конфигураций современных комплексов реального времени. Суть его в том, чтобы разнести функции HMI/SCADA и функции реального времени по разным уровням иерархии системы. Контроллеры нижнего уровня, работающие с объектным вводом/выводом и оснащенные ОС РВ, передают данные для отображения и т.д. на компьютеры c NT, расположенные на более высоком уровне. В этом случае непосредственно к NT требования реального времени, как правило, не предъявляются, поскольку это прерогатива нижнего уровня.
Сейчас существует достаточно много локальных продуктов для коммуникаций между уровнями (DDE-серверы для некоторых ОС РВ, сетевые протоколы), но, как правило, эти решения носят частный характер. Ситуация существенно изменяется, с развитием стандарта OPC (OLE for Process Control), когда пользователи ОС РВ нижнего уровня получают стандартный выход в мир офисных технологий.
Использование NT в системах мягкого реального времени
WINDOWS NT содержит в себе элементы реального времени, в частности, классы приоритетов реального времени и эффективную систему обработки прерываний. Учитывая эти особенности и ограниченно используя некоторые средства (например GUI), можно применять эту ОС для построения приложений мягкого реального времени.
Применение различных "трюков" для разработки приложений жесткого реального времени
В принципе, можно попытаться создать полностью предсказуемое приложение в стандартной среде NT, обратив особое внимание на процедуры загрузки и "закрытия" системы и на взаимодействие с другими процессами. Можно, например, написать приложение, основная часть которого исполняется в режиме ядра NT. В этом случае большая часть кода этого приложения должна лежать внутри драйвера. Можно использовать и другие хитрости, стараясь свести к минимуму вероятность возникновения непредсказуемых ситуаций. Но для этого необходим программист высочайшей квалификации, хорошо знающий WINDOWS NT и способный "вычислить" все потенциальные опасности. Естественно, что при создании такого приложения он сможет использовать лишь очень ограниченный набор возможностей NT. Кроме того, подобные приложения чрезвычайно трудно сопровождать и модифицировать.
Перенесение API-интерфейса Win32 в ОС РВ
Этот подход понятен и реализуем. Он уже осуществлен в некоторых ОС РВ. В частности, в VxWorks. Преимущество этого подхода в том, что API-интерфейс WIN32 опирается в данном случае на полностью предсказуемое и надежное ядро ОС РВ. Но при этом пользователь системы получает только одну из возможностей WINDOWS NT, а именно дополнительный программный интерфейс. И, конечно, в этом случае не может быть и речи об использовании стандартных приложений WINDOWS NT в ОС РВ.
Модификации ядра
Только этот подход способен превратить WINDOWS NT в настоящую ОС РВ с сохранением большинства ее возможностей. Однако исходные тексты ядра WINDOWS NT принципиально недоступны для третьих фирм - это одно из положений политики Microsoft. Поэтому соответствующие модификации могут исходить только от самой компании, что в ближайшее время маловероятно, учитывая ее ориентацию на рынок ПО общего назначения.
Модификации уровня аппаратных абстракций WINDOWS NT (HAL) и дополнение стандартного ядра NT ядром реального времени.
Эти подходы использовались для создания расширений реального времени WINDOWS NT, поэтому остановимся на них подробнее.
Из всех перечисленных подходов к соединению возможностей NT и требований реального времени только первый и последний действительно интересны. Все остальные либо неосуществимы, либо очень ограничены в использовании. Так было всегда (вспомним UNIX). Попытки соединить новую мощную технологию с требованиями реального времени развивались по двум направлениям:
· "втащить" новую OC на уровень контроллеров (клоны UNIX реального времени);
· реализовать в системах нижнего уровня стандартные коммуникационные интерфейсы к системе верхнего уровня (TCP/IP, RPC).
Тот же процесс мы наблюдаем и сейчас: стандарт OPC и расширения реального времени для NT развиваются параллельно.
Расширения реального времени для WINDOWS NT
Но что здесь можно изменить? Реально ли усовершенствовать WINDOWS NT без потери тех возможностей, которые она предоставляет? Попытаемся ответить на эти вопросы. Однако заметим прежде - все предлагаемые решения являются самостоятельными продуктами и никак не связаны с Microsoft. Какие же лазейки нашли создатели расширений реального времени для NT, если учесть, что исходные тексты ядра WINDOWS NT недоступны?
На рис. П-11 приведена упрощенная структура WINDOWS NT.
Приложения пользователя
Ядро NT
Драйверы устройств
Уровень аппаратных абстракций (HAL)
Рис. П-11. Упрощенная структура NT
Уровень аппаратных абстракций (HAL - Hardware Abstraction Layer) - нижний уровень ПО, "скрывающий" от исполнительной системы NT аппаратно-зависимые детали, такие как контроллеры ввода-вывода и контроллер прерываний. Первый вход в обслуживание прерываний происходит именно на HAL-уровне. Исходные тексты HAL можно получить, подписав специальное соглашение с Microsoft.
Ядро WINDOWS NT и драйверы. Единственной модифицируемой частью ядра являются драйверы устройств.
Таким образом, можно заключить, что все расширения реального времени могут быть построены только на модификациях уровня аппаратных абстракций и создании специфических драйверов.
Модификации уровня аппаратных абстракций
Решения, основанные на данном подходе, были предложены фирмой VenturCom. Структура расширений WINDOWS NT этого типа приведена на рис. П-12. Так как аппаратные прерывания попадают вначале в HAL и только затем передаются ядру, логично использовать прерывания от таймера для создания на базе модификаций HAL дополнительного диспетчера, а именно диспетчера нитей реального времени. Прерывания же, "не интересные" диспетчеру, можно передавать по прежней цепочке в ядро WINDOWS NT. Таким образом, появляется шанс выстроить достаточно развитую систему поддержки приложений реального времени. В итоге получаются два набора приложений: стандартные приложения NT и приложения реального времени, управляемые HAL-диспетчером. Причем стандартные приложения "не подозревают" о приложениях реального времени. И если на этом остановиться, то получится просто два класса задач, которые исполняются на одном процессоре, но никак не связаны между собой. В частности, приложения реального времени не будут иметь доступа к набору сервисов WINDOWS NT (графический интерфейс, сети и т.д.). Поэтому разработчики, выбравшие такой вариант реализации, должны сами обеспечить интерфейс между приложениями реального времени и стандартными приложениями NT. Специалисты VenturCom предлагали решить эту проблему на двух уровнях. С одной стороны, существует механизм взаимодействия приложений реального времени с приложениями NT через разделяемую память (на рис. П-12 этот механизм показан стрелкой IPC - Inter Process Communication), а с другой стороны, специфический драйвер NT позволяет стандартным приложениям "увидеть" подсистему реального времени как устройство (на рис. П-12 этот механизм показан стрелкой DD_Com - Device Driver Communication).
Приложения пользователя
Ядро NT
Приложения реального времени
Драйверы устройств
Уровень аппаратных абстракций (HAL) + Диспетчер (HAL)
Рис. П-12. Структура расширений NT в версии VenturCom
Дополнение стандартного ядра WINDOWS NT ядром реального времени
Этот подход лежит в основе предложений фирм Radisys, Imagination и LP Elektronik. Имеются две принципиально разные его реализации:
· разместить ядро реального времени внутри программы обслуживания прерываний WINDOWS NT или в драйвере устройства;
· разместить ядро реального времени вне адресного пространства WINDOWS NT.
Реализация первой идеи была предложена компанией LP Elektronik. Суть ее в том, что на шину ISA ставится дополнительная плата (LP-Realtime Accelerator), снабженная таймером и имеющая возможность управлять большинством линий прерываний ISA. Кроме того, LP Elektronik предлагает технологию написания программ обработки прерываний (ISR) от этой платы. Эта технология позволяет, в частности, расширить программу обработки прерываний до размеров полноценного ядра ОС РВ.
Строго говоря, LP Elektronik не предлагает собственных расширений реального времени для WINDOWS NT, однако на базе ее технологии в NT было внедрено ядро ОС РВ VxWorks. Способ взаимодействия между процессами VxWorks и WINDOWS был найден остроумный и легко реализуемый: между NT и VxWorks построена "псевдосеть" ТСР/IP. Для этого пришлось разработать всего лишь два драйвера TCP/IP - один для WINDOWS, и один для VxWorks.
Фирма Radisys осуществила второй подход, итогом реализации которого стал продукт INtime, основанный на ядре реального времени ОС iRMX. Понятно, что и здесь не обошлось без модификации уровня HAL и разработки специфического драйвера. Этот драйвер, как и в остальных реализациях расширений реального времени, предназначен для взаимодействия между процессами NT и процессами реального времени. Radisys разработала также оригинальный механизм внедрения одной ОС в другую. Этот механизм управляет одновременным исполнением и целостностью ядер WINDOWS NT и реального времени, осуществляет защиту памяти и разделяет адресные пространства процессов. Процессы и прерывания реального времени при этом всегда имеют приоритет по сравнению с процессами и прерываниями WINDOWS NT. Структура расширений WINDOWS NT c дополнительными ядрами реального времени приведена на рис. П-13.
Пока существуют операционные системы (ОС) настольного класса, будет существовать спрос на решения, позволяющие использовать такие ОС во встраиваемых системах (ВС) и в задачах реального времени. Одним из наиболее эффективных решений такого типа, охватывающих широкий диапазон прикладных областей, является продукт RTX компании IntervalZero.
Если бы на рынке осталась всего одна ОС, отвечающая требованиям абсолютно всех задач — офисных, встраиваемых, ответственных, реального времени и т.д. — то, как это ни странно, такая фантастическая ситуация устроила бы очень многих, если не всех. Получив опыт работы с определенной ОС в определенном классе приложений, многие хотели бы использовать этот опыт, а, следовательно, и саму ОС, в других сферах, включая те, для которых она изначально не предназначалась. Весьма успешной попыткой воплотить мечту об одной ОС для всех рынков выглядит расширение RTX (Real Time eXtension), добавляющее в стандартные офисные и встраиваемые ОС семейства Windows (кроме линейки Windows CE) поддержку реального времени.
Реальный шанс для воплощения основной идеи RTX — сделать так, чтобы популярную недорогую ОС общего назначения можно было комфортно использовать во встраиваемых системах и системах жесткого реального времени — появился лишь с началом эпохи Windows NT. Став, по сути, первой профессиональной ОС с человеческим лицом, платформа Windows NT открыла новую эру в истории корпорации Microsoft и в общей истории операционных систем.
Что касается рынка встраиваемых компьютерных технологий (ВКТ), то роль Windows NT в его формировании и развитии тоже весьма велика. В середине 1990-х гг. ВС на базе Windows NT стали возникать массово. Для комфортного использования Windows NT во встраиваемых системах и задачах реального времени разработчикам не хватало лишь трех условий:
– возможности уменьшать размеры ОС до приемлемых величин;
– средств обеспечения работы ОС в бездисковых конфигурациях (из ПЗУ или флэш-памяти), в т.ч. без монитора и без клавиатуры;
– средств обеспечения детерминированного поведения.
Осознав эти пользовательские потребности, компания выпустила свои теперь уже легендарные продукты Component Integrator и RTX. Component Integrator представлял разработчику ОС Windows NT в качестве «кубиков» — отдельных компонентов, из которых он мог легко собрать ОС с необходимой только ему функциональностью, расширение же RTX позволяло добавлять в обычную настольную ОС Windows NT поддержку работы в режиме жесткого реального времени.
В результате применения инструмента Component Integrator значительно (нередко в несколько раз) снизились требования к аппаратуре, а также еще более повысились надежность и производительность. Впоследствии технология Component Integrator была куплена корпорацией Microsoft, и под именем Component Designer стала основой нового бизнес-направления Microsoft: производство и поставка встраиваемых ОС, линейки продуктов Windows Embedded. Что касается RTX, то этот продукт позволил себе и вовсе доселе немыслимое: использовать стандартные настольные ОС Microsoft, в том числе и для приложений реального времени.
Нужно внести ясность относительно названия компании-производителя. RTX — детище компании VenturCom. В 2004 г. VenturCom сменила название на Ardence, затем в 2006 г. Ardence была куплена корпорацией Citrix, наконец, в 2008 г. на основе подразделения корпорации Citrix, занимавшегося ПО реального времени, была создана отдельная компания, получившая название IntervalZero Inc. Но, несмотря на все эти пертурбации, сегодня решения серии RTX развивает и поддерживает та же команда, что и раньше, поскольку костяк технических специалистов и менеджеров компании VenturCom перешел во вновь образованную компанию IntervalZero.
За 10 с лишним лет существования RTX удобство и эффективность этого продукта смогли оценить очень многие разработчики, реализовавшие на его основе сотни тысяч проектов. И все это время RTX успешно развивался, обрастая новыми функциями и возможностями. Посмотрим, что представляет собой современный RTX с технической точки зрения.
Продукт RTX состоит из двух частей. Первая часть — пакет разработчика RTX SDK (Software Development Kit) — предназначен для создания собственных приложений для работы в среде RTX. Вторая часть — подсистема исполнения RTX Runtime — представляет собой непосредственно подсистему реального времени для обслуживания приложений RTX. Подсистема RTX Runtime устанавливается на целевые системы, где предполагается запуск RTX-приложений. Пакет разработчика также включает подсистему реального времени, поэтому разрабатываемые приложения RTX можно запускать и отлаживать непосредственно на локальном месте разработчика. Кроме того, очень ценным свойством SDK является его тесная интеграция со средой разработки Visual Studio от компании Microsoft.
На момент написания статьи последней версией RTX являлась RTX 2011. С версии RTX 2009 нумерация несколько изменилась. Ранее версии имели номера (вплоть до 8.1.1), теперь вместо номеров используются годы выпуска. Компания IntervalZero обеспечивает 10-летний срок поддержки своих продуктов, поэтому приобрести системы исполнения к ранее купленной версии не составляет труда. Самая ранняя, поддерживаемая на данный момент версия, — RTX 7.1.
Каким образом на основе Windows можно создать систему реального времени? Стоит сразу отметить, что все предлагаемые на рынке решения не меняют функциональности и возможностей самой Windows, в ее поведении и работе ничего не меняется. Подсистема, реализующая функции системы реального времени, работает «рядом» с Windows. Обычные задачи Windows выполняются в недетерминированной среде, как и раньше. Один из вариантов реализации подобного механизма — разделение ресурсов между Windows и подсистемой реального времени. Подобный подход реализовала, например, компания TenAsys, предлагающая продукт INTime. При использовании INTime на одной аппаратной платформе запускаются две виртуальные машины — с Windows и с подсистемой реального времени INTime.
Здесь в целом неважно, какая ОС выполняется параллельно с подсистемой реального времени, поддержка Windows определяется наличием модифицированного уровня аппаратных абстракций HAL для работы в таком режиме и наличием интерфейсов API для связи задач, работающих в режиме реального времени и в Windows-среде. С популяризацией многоядерных архитектур стало возможным выделение отдельных ядер под Windows и под систему реального времени. Однако довольно сложная архитектура INTime не позволяет добиться высокой производительности в задачах реального времени.
В отличие от описанного подхода RTX тесно интегрируется с ОС Windows. На рисунке 1 приведена его архитектура. RTX дополняет стандартный HAL Windows своим расширением (RTX HAL Extension). На этом уровне кроме организации доступа к аппаратуре обрабатываются прерывания от таймера подсистемы реального времени. Непосредственно функциональность реального времени реализует слой RTSS (Real-Time SubSystem). Это ядро всей подсистемы реального времени. Здесь находится свой планировщик, который оперирует выполнением задач реального времени и предоставлением ресурсов задачам Windows-среды. Фактически, любая задача RTSS имеет более высокий приоритет, нежели любая задача, выполняющаяся в Windows. Кроме того, этот слой полностью реализует API реального времени (Real-Time API — RTAPI), на основе которого создаются приложения подсистемы RTSS.
Приложения реального времени (RTSS Process) выполняются здесь на уровне ядра Windows, имеют те же привилегии и ограничения, что и драйверы устройств. Этот подход отличается от других реализаций (например, INTime обеспечивает приложениям реального времени пользовательский режим, собственное адресное пространство и изоляцию). Но за счет этого достигается очень быстрое переключение контекста задач.
Доступ к функциям RTAPI возможен как для процессов RTSS, так и для обычных приложений Win32. Это позволяет выделять в Windows-задачах отдельные, критичные ко времени выполнения, участки. Такой возможности лишены системы, где Windows и подсистема реального времени работают параллельно. Кроме того, расширение интерфейса Win32 API функциями RTSS позволяет приложениям Win32 и приложениям RTSS обмениваться данными.
Как можно видеть из рисунка 1, в составе RTX присутствуют компоненты, организующие для приложений RTSS сеть реального времени и работу в реальном времени с устройствами USB. Это стек протоколов RT-TCP/IP и стек RTX USB. Сетевой стек обеспечивает работу всех сетевых протоколов и физического уровня в детерминированном режиме. Аналогично работает поддержка USB — все компоненты работают с полностью предсказуемыми задержками.
Наличие стека реального времени означает работу всех функций и драйверов с гарантированным временем, т.е. разработчик может быть уверен, что входящий пакет будет обработан, и исходящие данные будут доставлены до физического уровня за ограниченный промежуток времени. При этом наличие стека RT-TCP/IP не означает, что вся сеть будет работать в реальном времени, даже если данный стек будет стоять на всех узлах сети. Сеть состоит из многих элементов, в частности, в ней есть оборудование, которое реализует ее топологию. На физическом уровне сети могут происходить различные процессы, дополнительное оборудование может вносить свои задержки, кроме того, ОС Windows тоже не бездействует в плане сетевой активности. Поэтому сетевой стек реального времени позволяет получить гарантированную производительность, но не гарантирует работу всей сети без сбоев и задержек. Стек RT-TCP/IP предназначен только для достижения максимума производительности в сетевых задачах. Наиболее приближенную к реальному времени работу сети можно получить, если выделить все сетевые адаптеры для RTX в один сетевой сегмент.
Что RTX может дать разработчику? Во-первых, использование стандартной ОС Windows позволяет обойтись без дополнительного аппаратного обеспечения и специализированных систем реального времени. Весь проект от начала до конца может быть реализован специалистами, ранее разрабатывавшими только обычные Windows-приложения, поскольку API RTX максимально приближен к API Win32 и не требует много времени на освоение. Благодаря огромному сходству между этими двумя API разработчикам, никогда не имевшим дело с программированием систем реального времени, не составит большого труда научиться создавать приложения реального времени под RTX. Этому весьма поспособствует и интеграция со знакомой системой разработки Microsoft Visual Studio. Все это в совокупности позволит значительно (очень часто в разы) сократить затраты на развертывание проекта, поскольку стоимость владения и применения RTX сопоставима (а в большинстве случаев ниже) со стоимостью традиционных ОСРВ.
Во-вторых, и это очень важно, применение RTX не является неким компромиссом или ограничением возможностей. Разработчик получает современную, мощную, быструю и гибкую подсистему реального времени, не уступающую по функциональности классическим ОСРВ. Абсолютно все процессы в подсистеме RTSS детерминированы, а это является основой любой системы реального времени.
Кроме того, несмотря на тесную интеграцию с операционной системой, RTX имеет такое важное свойство как устойчивость к сбоям среды Windows. Подсистема RTSS умеет корректно обрабатывать завершения Windows, как штатные, так и аварийные («синий экран»). Также в RTX имеется механизм, с помощью которого можно сделать доступной память, которую «не видит» Windows. Этой цели служат, в частности, функции PAE (Physical Address Extensions), расширяющие адресное пространство до 36 разрядов и позволяющие получать на 32-разрядных системах доступ к 64 Гбайт памяти.
Еще одной очень важной особенностью RTX является организация связи между задачами Win32 и RTSS. Механизмами взаимодействия процессов (IPC) являются привычные события, мьютексы, семафоры и общая память. При этом взаимодействие между детерминированной подсистемой RTSS и недетерминированной подсистемой Windows организовано так, чтобы исключить их перекрестное влияние на работу друг друга. Еще одним механизмом, направленным на обеспечение безопасности взаимодействия подсистем, является механизм прокси-процессов, осуществляющий обращение из среды Windows к RTSS-окружению.
Однако самым важным свойством, которое появилось с версии RTX 2009, является поддержка для задач RTSS работы в режиме SMP — симметричной мультипроцессности. В версии RTX 2011 было отменено деление продуктов по признаку наличия либо отсутствия поддержки SMP. Теперь при разработке программ с помощью SDK всегда есть возможность использовать SMP, а Runtime отличаются только числом ядер, которые можно выделить под RTX (от 1 до 31). В сочетании с различным оборудованием запуск RTX возможен в различных режимах.
Данный вариант поддерживали предыдущие версии без SMP. Это единственный вариант работы для RTX Runtime Solo с поддержкой выделения одного ядра. RTX и Windows выполняются здесь на одно- или многопроцессорной (многоядерной) системе. Возможны два варианта:
– разделяемый режим:
в этом случае RTX и Windows работают на одном ядре процессора, разделяя его ресурсы. Соответственно и возможности такой системы довольно ограничены, особенно при большой загрузке. Такой вариант применим для систем с не очень большими требованиями к подсистеме реального времени. Если загрузка довольно серьезная, то лучше применить другой режим;
– режим с выделенным процессором:
в этом случае RTX полностью занимает одно процессорное ядро. Естественно, для этого необходимо, чтобы в системе было более одного ядра (или процессора). На остальных ядрах выполняется Windows. В такой системе RTX уже не требуется делить вычислительные ресурсы с Windows, потому здесь возможна реализация более серьезных систем реального времени. В современных условиях, когда широко распространены процессоры с двумя и более ядрами, выделение отдельного ядра под RTX не влечет за собой каких-либо серьезных затрат.
Этот режим предполагает наличие нескольких ядер или процессоров. Режим SMP поддерживает выделение под задачи RTX от 2 до 31 процессорного ядра, которые используются по возможности с полностью симметричной загрузкой. На оставшихся ядрах будет выполняться Windows. Реализация такого режима позволяет строить системы реального времени, которые крайне требовательны к производительности и вычислительным мощностям и занимаются очень мощными вычислениями.
Наличие различных версий SDK и Runtime позволяет управлять своими вложениями в систему посредством выбора нужного числа поддерживаемых ядер. Чем больше в системе ядер, поддерживаемых RTX, тем дороже конечное решение. Все Runtime, даже с поддержкой выделения 31 ядра, сохраняют поддержку работы на одно- или двуядерных системах, где нельзя реализовать режим SMP для RTSS-задач. Число используемых подсистемой RTSS ядер задается в настройках и ограничено лишь тем максимумом, который поддерживает установленный в систему Runtime.
Несмотря на сложность архитектуры RTX, для пользователя общение c RTX является простым и прозрачным. Например, свойства подсистемы RTX задаются из одного окна (см. рис. 2). К тому же в составе RTX SDK имеется обширная документация по работе с RTX (см. рис. 3). Программисты, знакомые с Microsoft Visual Studio, имеют возможность пользоваться данным инструментарием для разработки задач RTX. В среду разработки добавляются шаблоны возможных вариантов приложений RTX (см. рис. 4). Стандартные отладочные механизмы Microsoft Visual Studio доступны при этом для отладки и приложений RTX. По сути, вся разработка ведется привычными методами и с помощью известных инструментов.
Еще раз о Windows и реальном времени
Одна из типичных ситуаций: ноутбук с 64-разрядной Windows 7, на котором работает прикладная программа, обрабатывающая данные, регулярно приходящие из сети или от некоторой аппаратуры. Все функционирует, как задумано, кроме того, что иногда возникают непредсказуемые задержки, связанные с работой самой Windows, т.е. планировщика. Это ожидаемо, так как и Windows не система реального времени (больше подходит название «система мягкого реального времени»), да и ноутбук вовсе не специальный сервер, предназначенный для транзакций в реальном времени.
Обидно, что для преодоления этого последнего и, казалось бы, несущественного препятствия приходится прикладывать значительные усилия. Предлагается и переход на другие операционные системы и надстройки над Windows (по существу ее подмена) вроде среды RTX, и написание драйверов режима ядра, что выглядит иногда как стрельба из пушек по воробьям. Однако иначе невозможно преодолеть принципиальное ограничение Windows, запрещающее прикладным программам монопольно владеть ресурсами в обход использования механизма драйверов, написание которых становится все сложнее и сложнее и уже требует цифровой подписи и других особенностей, никак не связанных с решаемыми задачами.
На мой взгляд, данное несоответствие обусловлено противоречием между общим назначением Windows и конкретностью частных задач. В общем случае разработчики ОС справедливо не допускают прикладные задачи до полного контроля над компьютером (помимо использования аппарата драйверов), иначе устойчивая работа системы станет невозможной. Но в данном конкретном случае компьютер и предустановленная на нем Windows куплены только ради одной прикладной программы и как раз в этом случае данная программа вполне могла бы монопольно владеть ресурсами, причем других прикладных задач при ее работе нет.
Аппаратная поддержка
Разработчики архитектуры х86 предусмотрели некоторую поддержку подобных ситуаций [1]. Речь идет об уровне привилегий ввода-вывода IOPL (биты 12 и 13) регистра флагов EFLAGS. Если установить оба этих бита в единицу (т.е. сделать IOPL=3), то обычная прикладная программа сможет напрямую обращаться к портам ввода-вывода и, главное, сможет прямо задавать команды CLI/STI , закрывающие и открывающие прерывания.
Имея нужный уровень IOPL, прикладная программа могла бы выполнить очередную транзакцию гарантированно без переключений в это время на другие задачи. В предельном случае прикладная программа вообще могла бы провести целый сеанс, выключив, точнее «заморозив» Windows, а затем включив ее снова. Это вполне возможно, хотя и потребует после такой «разморозки» ОС некоторых дополнительных действий, вроде коррекции программных часов Windows по аппаратным часам компьютера. В любом случае приостанавливается работа планировщика, и влияние Windows в этот момент полностью исключается.
Таким образом, не используя надстройки или другие ОС, и не разрабатывая драйверы, можно было бы вернуться в некотором роде к временам Windows-98 или даже MS-DOS, когда прикладная программа могла в принципе делать что угодно (и поэтому зависание и крах системы были обычным делом), однако сложностей с реальным временем, по сути, не было.
Исправление ядра
Прежде всего, исправлять придется ядро Windows 7 в его 64-разрядном варианте, т.е. файл ntoskrnl.exe из папки Windows\system32 , причем после загрузки под этим именем там находится совсем другой файл – 32-х разрядная версия ядра, которая вообще не используется на 64-х разрядных процессорах. Можете сами в этом убедиться, сделав себя владельцем этого файла и переименовав или даже стерев его. 64-разрядная Windows 7 после перезагрузки будет работать, как ни в чем не бывало и 32-х разрядные приложения нормально выполняются. То же справедливо и для файла ntkrnlpa.exe (32-х разрядной версии ядра для памяти более 3 Гбайт): т.е. и он присутствует, но никак не используется.
Для доступа к файлу настоящего ядра нужно, например, загрузить другую ОС с компакт-диска, используя удобные специальные сборки типа «Реаниматор», обеспечивающие доступ к исходным дискам C:, D: и т.д.
Кроме этого, в Windows 7 имеется документированный способ подключить другое ядро, например, файл с именем nt1skrnl.exe с помощью директивы:
Откуда возьмется другое ядро? Для начала можно просто скопировать в системной папке под таким именем исходное. Теперь все опыты можно вести с копией в nt1skrnl.exe , не трогая исходного ядра. И всегда можно вернуться к исходному ядру, опять скопировав его под этим именем или выполнив директиву подключения стандартного ядра:
Файл ntoskrnl.exe представляет собой несколько мегабайт команд в 64-разрядном режиме. Куда же в нем вставлять команды установки IOPL?
Подсказку дает необходимость в Windows следить за содержимым регистра флагов у прикладных задач. Ядро постоянно «приводит в порядок» флаги задачи пользовательского уровня, гася запрещенные по маске-константе. Младшая часть этой константы 0DD5 и «выдает» работу с флагами пользовательской программы, например:
Здесь ядро погасило запрещенные биты, в том числе и IOPL, а затем принудительно разрешило флаг прерываний. Достаточно заменить одну команду на другую:
и при выходе из ядра в пользовательский уровень IOPL станет равным 3.
Таких мест в ядре оказалось несколько и, методом проб и ошибок, был найден соседний фрагмент, который в данном случае и используется:
Правда, здесь флаг разрешения прерывания устанавливается почему-то экзотическим способом с помощью команды BTS, очевидно как более короткой. Однако прямая установка командой:
ничуть не длиннее. Используя эту команду, устанавливаем заодно и максимальный уровень IOPL:
Поскольку изменились байты, контрольная сумма по адресу 00000140 (которую можно рассчитать с помощью CheckSumMappedFile) также должна поменяться, в данном случае с 5553E5 на 55С260
Таким образом, после всех исправлений, список отличий от исходного ядра, выведенный с помощью стандартной утилиты fc, следующий:
Тестирование исправления
Теперь можно производить перезагрузку Windows 7 с входом в расширенное меню по нажатию F8 и выбора режима «отключение обязательной проверки подписи драйверов», поскольку цифровая подпись уже не совпадает. В результате исправленное ядро из файла nt1skrnl.exe будет загружено и запущено.
Проверим работу исправления ядра на примере простейшей 32-разрядной тестовой программы на языке PL/1 [2]:
Заключение
Итак, на том же самом компьютере, на той же самой ОС, и почти не меняя прикладной программы (были только добавлены команды CLI/STI ), удалось решить поставленную задачу за счет нетривиальной, но примитивной «доработки» самой ОС. При этом был получен режим «реального времени» в том смысле, что исключено вмешательство планировщика и служебных процессов во время работы прикладной программы. Конечно, подобного же эффекта можно достичь и через аппарат драйверов, но это требует значительно больших изменений в построении ПО, а кроме этого, не используется аппаратная поддержка, предусмотренная разработчиками архитектуры х86 для прикладных программ в подобных случаях. Причем такая поддержка позволяет не переходить с пользовательского режима на уровень ядра.
Простым исправлением удалось преодолеть противоречие между общим назначением Windows и требованием конкретной задачи. В результате исправления частично произошел возврат к идеологии ОС эпохи Windows 98, когда прикладная задача могла захватить компьютер в монопольное использование и максимально быстро реагировать на происходящие события. Хотя такой режим в общем случае недопустим, для частных задач его вполне можно использовать, и было бы целесообразно иметь подобный режим как документированное средство Windows. Это позволило бы проще применять данную ОС для более широкого класса задач.
Среда реального времени, аппаратная или программная, характеризуется требованиями выдерживания критического срока. Аппаратные системы реального времени (например, система управления атомной электростанцией) имеют критические сроки, которые должны соблюдаться системой, чтобы избежать катастрофических сбоев, приводящих к выходу из строя оборудования или к человеческим жертвам.
Программные системы реального времени (например, автомобильные системы оптимизации расхода топлива) имеют критические сроки, которые могут быть пропущены системой, но своевременность по-прежнему является желаемым свойством. В системах реального времени у компьютеров есть сенсорные устройства ввода и управляющие устройства вывода. Конструктор компьютерных систем реального времени должен знать наихудшие значения задержек между временем генерирования прерывания входным устройством и временем возможного управления реакцией выходного устройства со стороны драйвера устройства. Этот анализ наихудшей ситуации должен принимать в расчет задержки операционной системы, возникающие как из-за задержек приложения, так и из-за задержек, вносимых драйверами устройств.
Поскольку Windows не допускает управляемой установки приоритетов IRQ-запросов устройств и приложений пользовательского уровня только в случае пребывания процессорного IRQL-уровня в пассивном состоянии, Windows обычно не подходит в качестве операционной системы реального времени. В конечном счете, наибольшие задержки определяются не Windows, а устройствами системы и драйверами устройств. Этот фактор становится проблемой, когда разработчики систем реального времени используют какое-нибудь стандартное оборудование.
У конструкторов могут возникнуть сложности в определении продолжительности наихудших задержек ISR или DPC стандартных устройств. Даже после тестирования конструктор не может гарантировать, что частный случай в живой системе не заставит эту систему пропустить критический срок. Более того, суммарное значение всех задержек системных DPC и ISR может существенно превышать значение, допустимое для чувствительной ко времени системы.
Хотя требования реального времени есть у многих типов встроенных систем (например, у принтеров и автомобильных компьютеров), у Windows Embedded Standard 7 характеристики реального времени отсутствуют. Это просто одна из разновидностей Windows 7, позволяющая выпускать компактные версии этой операционной системы, подходящие для запуска на устройствах с ограниченными ресурсами. Например, устройство без сетевых возможностей опустит все компоненты Windows 7, связанные с работой в сети, включая средства управления сетью, а также адаптер и драйвера устройств стека протокола.
Кроме того, существуют сторонние производители, поставляющие для Windows ядра реального времени. Подход, используемый ими, заключается во встраивании их ядра реального времени в специализированный HAL и в принуждении Windows запускаться в качестве задачи в операционной системе реального времени. Задача, запускающая Windows, служит в качестве пользовательского интерфейса к системе и имеет более низкий приоритет по сравнению с задачами, ответственными за управление устройством.
Связывание ISR с конкретным уровнем прерывания называется подключением объекта прерывания, а разобщение ISR и записи IDT называется отключением объекта прерывания. Эти операции, выполняемые путем вызова функций ядра IoConnectInterruptEx и IoDisconnectInterruptEx, позволяют драйверу устройства «включать» ISR при загрузке драйвера в систему и «выключать» ISR, если драйвер выгружается.
Использование объекта прерывания для регистрации ISR препятствует тому, чтобы драйверы устройства возились непосредственно с аппаратными средствами прерывания (имеющими отличия, связанные с архитектурами процессоров), и избавляет от необходимости знать обо всех подробностях IDT. Это свойство ядра помогает в создании переносимых драйверов устройств, поскольку оно исключает необходимость программировать на языке ассемблера или отражать разнообразие процессоров в драйверах устройств.
Объекты прерываний предоставляют также и другие преимущества. За счет использования объекта прерывания ядро может синхронизировать выполнение ISR с другими частями драйвера устройства, которые могут использовать с IRS общие данные.
Более того, объекты прерываний позволяют ядру легко вызывать более одной ISR-процедуры для любого уровня прерывания. Если объекты прерываний создаются несколькими драйверами устройств и подключаются к одной и той же записи IDT, диспетчер прерываний вызывает каждую процедуру при возникновении прерывания на указанной линии прерывания.
Эта возможность позволяет ядру легко поддерживать конфигурации, составленные из последовательных цепей, в которых несколько устройств совместно используют одну и ту же линию прерывания. Цепь прерывается, когда одна из ISR-процедур заявляет о правах собственности на прерывание, возвращая статус диспетчеру прерываний.
Так сложилось, что на системе, где была запущена команда, этот вектор соответствовал встроенному карт-ридеру 7-в-1, представляющему собой комбинацию из устройств чтения флеш-карт Secure Digital (SD), Compact Flash (CF), MultiMedia Card (MMC) и карт других типов, и у каждого устройства имелось свое собственное прерывание. Поскольку они были сгруппированы производителем в одно устройство, вполне разумно было его прерываниям использовать один и тот же вектор.
Общие прерывания часто являются причиной высокой латентности прерываний, а также могут стать причиной нестабильной работы системы. Обычно их использование нежелательно и выражается в побочном эффекте наличия на компьютере ограниченного количества физических линий прерывания.
Например, в предыдущем примере с кард-ридером 7-в-1 намного лучше было бы, чтобы для каждого устройства было свое собственное прерывание и чтобы один драйвер управлял различными прерываниями, зная, от какого устройства пришло прерывание. Но расход четырех IRQ-линий на одно устройство быстро приводит к исчерпанию IRQ-линий. Кроме того, в любом случае каждое PCI-устройство подключается только к одной IRQ-линии, поэтому кард-ридер вообще не может использовать более одной IRQ-линии.
Еще одна проблема, связанная с генерированием прерываний по IRQ-линии, заключается в том, что неправильное управление IRQ-сигналом может привести к недопустимому пику прерываний (interrupt storms) или к возникновению других разновидностей взаимных блокировок, поскольку пока ISR-процедура не подтвердит получение сигнала, он выставляется на «высоком» или «низком» уровне. Более того, контроллер прерываний должен, как правило, получать также и сигнал завершения прерывания EOI.
Если какое-либо из этих событий из-за какого-нибудь сбоя не произойдет, система войдет в бесконечное состояние прерывания, или же следующие прерывания будут замаскированы, или же произойдет и то и другое. И наконец, прерывания на основе использования линий предоставляют плохую масштабируемость в мультипроцессорной среде. Во многих случаях оборудование принимает окончательное решение о том, работу какого процессора прервать из возможного набора, составленного из того, что отобрано для этого прерывания диспетчером устройств Plug and Play, и из того, что могут сделать небольшие драйверы устройств.
Поскольку связь основана на значении памяти и поскольку содержимое доставляется вместе с прерыванием, надобность в IRQ-линиях отпадает (общий системный лимит MSI-прерываний делается равным количеству векторов прерываний, а не количеству IRQ-линий), отпадает также и необходимость в ведущей ISR-процедуре для запроса у устройства данных, связанных с прерыванием, что снижает задержку. В связи с доступностью в данной модели большого количества прерываний, связанных с устройствами, фактически сводится на нет вся польза от применения общих прерываний, а за счет непосредственной доставки данных прерывания заинтересованным в этом ISR-процедурам еще больше уменьшаются задержки.
Читайте также: