Необходимые требования к ОС для обеспечения предсказуемости
Сегодня становится широко распространенным желание потребителей использовать Windows NT в системах реального времени. Для этого имеется ряд весомых, на первый взгляд, причин: Win32 API считается стандартом, а на его базе разработано огромное количество программ; графический интерфейс стал сегодня очень популярным; для NT имеется немало готовых решений для коммерческих применений; в среду NT включены многие виды средств разработки. Тем не менее, возможно ли использование Windows NT для разработки системы реального времени?
Несмотря на то, что сегодня Windows NT не отвечает в полной мере требованиям, предъявляемым к операционной системе реального времени, давление рынка привело к появлению коммерческих решений, расширяющих NT возможностями обработки в реальном времени.
Система реального времени (СРВ) - это аппаратно-программный комплекс, который должен своевременно и предсказуемо реагировать на поступающие извне раздражители. Основное требование к СРВ - своевременность обработки событий. Реакция на событие должна уложиться в пределы заранее определенного лимита времени, а превышение этого лимита или опоздание считается программным сбоем.
В обычных интерактивных системах, не являющихся СРВ, например, в текстовом редакторе, превышение временного лимита не считается программным сбоем, а классифицируется как проблема производительности, которая может быть решена путем установки более мощного процессора.
Еще одним важным требованием к СРВ является одновременная обработка событий: если несколько событий происходят одновременно, все они должны быть обработаны своевременно. Это означает, что имманентным свойством системы реального времени должен быть параллелизм. Чтобы этого добиться, необходимо установить более одного процессора или придерживаться многозадачного подхода.
В зависимости от отношения к опозданиям системы реального времени делятся на "жесткие" (hard) и "мягкие" (soft).
В жесткой системе:
Хорошим примером жесткой системы реального времени может служить система управления движением воздушных судов. Очевидно, что бессмысленно посылать команду на изменение курса самолета или космической станции после столкновения.
В мягкой системе реального времени:
Примером мягкой системы является подсистема сетевого интерфейса. Если подтверждение о приеме посланного пакета не поступило после истечения определенного времени, то пакет считается потерянным. В этом случае можно просто повторить посылку пакета и примириться со значительным снижением производительности системы.
Итак, разница между жесткой и мягкой системами зависит от предъявляемых к ним требований. Система называется жесткой, если "система не должна опаздывать никогда", и мягкой, если "система не должна опаздывать, как правило".
Не следует путать операционную систему реального времени (ОС РВ) с системой реального времени. Первая ОС используется для создания системы реального времени. ОС РВ должна быть предсказуемой - это не значит, что она должна быть быстрой, это означает, что при построении СРВ можно добиться того, чтобы максимальное время, затрачиваемое на определенную работу, укладывалось в заранее установленный лимит, сравнимый с требованиями приложения. Windows 3.11, например, даже на сколь угодно быстром процессоре бесполезна для построения СРВ, поскольку любое приложение может захватить управление и заблокировать все остальное.
Очевидно, что NT - многонитевая ОС, она позволяет вытеснение и тем самым удовлетворяет требованию 1 (см. врезку).
В Windows NT имеются два класса приоритетов: класс реального времени и динамический класс. Процессы в классе реального времени имеют фиксированный приоритет, менять который может лишь само приложение, тогда как приоритет процессов динамического класса может меняться диспетчером. Процесс имеет базовый уровень приоритета. Нить в процессе может иметь приоритет в диапазоне плюс/минус 2 около базового уровня или один из двух крайних уровней класса (16 или 31 для реального времени). Например, нить в процессе с базовым уровнем 24 может иметь приоритет 16, 22 - 26, 31. Очевидно, что гарантировать предсказуемость системы можно только при использовании процессов первого класса.
Казалось бы, второе требование также удовлетворено. Но малое число возможных уровней препятствует реализации СРВ на базе NT. Большинство современных ОС РВ позволяет иметь по крайней мере 256 различных уровней. Чем больше имеется уровней, тем более предсказуемо поведение системы. В Windows NT имеется только 7 различных уровней для нити в данном процессе. В результате многие нити будут выполняться с одинаковыми приоритетами и, как следствие, предсказуемость поведения системы будет посредственной. Более того, общее число уровней для всех процессов класса только 16 и положение не спасает даже замена нитей процессами, не говоря уже о том, что переключение контекста для процессов снижает производительность.
В ОС РВ вызовы системы синхронизации (семафоры или критические секции) должны уметь управлять наследованием приоритетов. В Windows NT это невозможно, поэтому требование 4 не удовлетворяется.
Еще одна проблема обусловлена реализацией некоторых вызовов системы GUI. Они обрабатываются синхронно (вызывающая нить приостанавливается, пока не завершится системный вызов) процессом, выполняемым с более низким приоритетом (динамического класса). В результате нить может помешать нити с более высоким приоритетом - возникает инверсия приоритета.
Таким образом, малое число приоритетов и невозможность решить проблему инверсии делают Windows NT пригодной только для очень простых СРВ.
Для тестирования системных вызовов был написан процесс (принадлежащий классу реального времени), содержащий вызовы системы синхронизации нитей, и измерялось время, затраченное на каждый вызов. При запуске на Pentium 100 МГц с 24 Мбайт памяти оказалось, что максимальное значение на вызове mutex достигает 670 мкс при среднем времени 35 мкс. Это произошло потому, что во время работы теста происходили обращения к диску и по сети. Если компьютер искусственно загрузить обращениями к диску и сетевой обработкой, то задержки возрастают аж до нескольких миллисекунд. Win32 API очень богат, но не предназначен для реального времени. Например, запросы mutex обрабатываются в порядке поступления, а не в порядке приоритетов, что снижает предсказуемость. Для синхронизации нитей в одном процессе критические секции следует предпочесть всем другим способам (этот вызов затрачивает всего несколько мкс по сравнению с 35 мкс на вызов mutex).
Несмотря на все достоинства API, ядро и менеджер ввода/вывода Windows NT недостаточно приспособлены к обработке событий реального времени на уровне приложений.
В Windows NT единственный способ управления аппаратурой - через драйвер устройства. Поскольку приложение реального времени имеет дело с внешними событиями, разработчик должен написать и включить в ядро драйвер устройства, дающий доступ к аппаратуре. Этот драйвер реагирует на прерывания, генерируемые соответствующим устройством.
Прерывания обрабатываются в два этапа. Сначала выполняется очень короткая программа обслуживания прерываний (ISR). Впоследствии работа завершается выполнением DPC - процедуры отложенного вызова. Возникает следующий поток событий:
ISR должно быть как можно короче, поэтому большинство драйверов выполняют значительную часть работы в DPC (которая может быть вытеснена другим ISR), ожидая окончания других DPC, ранее попавших в очередь (все DPC имеют одинаковый приоритет).
Из документации по NT следует, что ISR может быть вытеснена другим ISR с более высоким приоритетом, и что DPC имеет более высокий приоритет, чем пользовательские и системные нити. Но поскольку все DPC имеют одинаковый уровень приоритета и ISR должна быть сведена к минимуму, ваш DPC будет вынужден ждать других и ваше приложение будет зависеть от остальных драйверов устройств непредсказуемым образом. Задержки системных вызовов, описанные в предыдущем разделе, обусловлены именно тем, что DPC от драйверов жесткого диска и сети блокируют все другие.
В настоящих ОС РВ разработчик знает, на каком уровне выполняются драйверы всех других устройств. Обычно имеется свободное пространство для прерываний выше стандартных драйверов. Вся критическая работа выполняется в ISR, что позволяет настроить конфигурацию драйвера в зависимости от временных ограничений приложения.
Другим важным моментом при проектировании СРВ является политика управления памятью в ОС РВ. В Windows NT процессы выполняются в своем собственном пространстве памяти. Добиться этого позволяют механизмы виртуальной памяти и подкачки. Для бизнес-приложений это хорошо, но для СРВ, которая должна реагировать на внешние события с заранее определенным лимитом времени, это порождает непредсказуемость, особенно если система отправит страницу из памяти на диск. Windows NT позволяет захватить страницу в памяти посредством вызова функции VirtualLock. Тем не менее NT может разблокировать страницу и выгрузить ее на диск, если весь процесс неактивен
Итак, можно сделать вывод, что Windows NT, предназначенная в основном для классических приложений, не является хорошей платформой для поддержания обработки в реальном времени. Тем не менее на ее базе можно все-таки построить простую мягкую СРВ, время от времени допускающую опоздания.Следующие обстоятельства могут облегчить построение СРВ на базе NT:
Но для жесткой СРВ использование Windows NT невозможно - система реального времени никогда не будет предсказуемой.Что следует изменить в Windows NT, чтобы ее можно было использовать в жестких СРВ?
a) Класс процессов реального времени должен иметь больше уровней.
б) Необходимо решить проблему инверсии приоритетов.
в) Время, затрачиваемое каждым системным вызовом, должно быть предсказуемо и известно.
г) Система прерываний должна быть заменена целиком:
Готовы ли разработчики Microsoft ввести эти усовершенствования в NT или они полагают, что рынок слишком мал, и оставят его свободным для третьих фирм?
Существуют разные варианты использования технологии NT для разработки систем реального времени:
Во многих решениях производители модифицируют HAL или ядро NT. Политика Microsoft заключается в том, чтобы не допускать никаких модификаций ядра NT, кроме драйверов устройств. Это единственно возможный способ связи с ядром. Политика компании относительно HAL другая. HAL (Hardware Abstraction Layer) - уровень аппаратных абстракций - уровень, лежащий ниже программного обеспечения, который виртуализирует интерфейс NT с аппаратурой, допуская переносимость NT с одной аппаратной платформы на другую. Такие модификации HAL, как манипуляции с часами или замена методов обработки прерываний, представляются беспримерно незаконным использованием HAL. Они создают нестандартную среду и могут привести к проблемам сопровождения, если, например, Microsoft изменит HAL в следующих версиях. Поэтому различие в решениях, предлагаемых поставщиками, заключается в попытках сделать модификации HAL минимальными.
Также возможен перехват HAL посредством трюков с процессором Intel. Однако это можно реализовать только на платформе Intel. Механизмы перехвата посредством обработки исключительных ситуаций на уровне устройства поглощают определенную вычислительную мощность.
Подобное применение предполагает включение структур, обрабатывающих прерывания. Однако учитывая, что NT не предназначена для обработки в реальном времени это надо делать очень аккуратно.
Иногда вводят усовершенствования в механизм обработки прерываний. Единственный способ сделать это - перехватить прерывание, для чего необходимо добавить специальное аппаратное расширение. LP-Elektronik, например, перехватывает прерывание и использует затем NMI (немаскируемое прерывание, не используемое на уровне NT) для обработки событий реального времени. Этот подход применим только тогда, когда процессор имеет отдельный стек прерываний. Программа NMI должна быть написана аккуратно: в ней нельзя использовать вызовы ОС и она должна быть как можно короче, чтобы не потерять другие прерывания. Такое решение дает минимальную задержку прерывания, но требует дополнительной аппаратуры. Как и в других решениях, здесь необходим дополнительный механизм связи между NT и частью реального времени. Разница в том, что при этом требуется большая аккуратность в использовании NMI.
Добавление Win32 API к ОС, предназначенной для обработки в реальном времени, избавляет от необходимости модифицировать HAL или использовать другие трюки с NT. Преимущества такого подхода:
Недостатки:
Среди коммерческих реализаций этого подхода - QNX и VxWorks, использующие библиотеку Willows.
Мощность современных процессоров достаточна для одновременного функционирования NT и программ реального времени. Возможны две разновидности такого подхода:
В любом случае HAL должен быть модифицирован или по крайней мере перехвачен. В основном все такие решения похожи. В качестве иллюстрации можно привести следующее возможное решение с модификацией HAL.
Программу голубого экрана NT можно рассматривать, как упрощенную программу супервизора. Модифицируя ее внутри HAL, можно сделать простой мультизадачный механизм выхода из нее, запустить NT, как одну из задач с самым низким приоритетом и запустить нечто другое, как другую задачу. Это нечто другое может быть набором задач реального времени или полной ОС РВ.
В обоих случаях необходим механизм связи между частями реального времени и NT. Он может быть выполнен одним из двух способов. Первый заключается во введении альтернативного механизма межпроцессорных связей (IPC). Проще всего реализовать IPC с помощью разделяемой памяти. Недостатком такого протокола IPC является уровень приоритета, на котором выполняются пользовательские приложения NT. При втором способе интерфейс реализуется с помощью драйвера устройства, в результате чего у NT создается впечатление, что подсистема реального времени - это устройство.
Задачи реального времени используют собственный интерфейс с системой, в большинстве случаев отличный от Win32 API. Среда разработки может быть обычной для используемой ОС РВ средой и может взаимодействовать со средой NT. Задачи реального времени будут выполняться, не получая преимуществ от механизма защиты памяти NT. Особо аккуратно следует продолжать выполнение частей реального времени, когда NT рухнет и сгенерирует голубой экран. След памяти - это комбинация следа NT (8 Мбайт в стандартной конфигурации) плюс минимальные требования для части ОС РВ.
Простота части реального времени может привести к высокой производительности, которая зависит от используемого ядра реального времени. Преимущества здесь таковы:
Недостатки:
Известны следующие коммерческие реализации подхода, не требующего модификации аппаратуры: IMAGINATION с HyperKERNEL; RADISYS с комбинацией iRMX/NT; VenturCom с RTX, KPX и RTAPI.
В реализации фирмы RadiSys ОС РВ iRMX работает, как первичная ОС, загружающая Windows NT в качестве низкоприоритетной задачи. Пользователь работает только с NT, не видя и не чувствуя iRMX. Все управляющие функции выполняются, как высокоприоритетные задачи iRMX, изолированные в памяти от приложений и драйверов NT. Используя функции защиты памяти внутри процессора Intel, Windows NT защищена от задач реального времени.
Комбинация iRMX/NT преодолела трудности, которые возникают при модификации HAL и оставляют пользователя уязвимым при сбоях жесткого диска, сбоях драйверов и системных сбоях NT ("голубой экран смерти"). В этом решении управляющая программа в случае краха NT может либо продолжить нормальное выполнение, либо произвести правильное закрытие системы (shutdown).
Реализация фирмы VenturCom состоит из двух этапов. На первом - мягкая реализация RTX 3.1 содержит интерфейс прикладной программы реального времени RTAPI, который дает время реакции 1-5 мск. RTAPI 1.0 работает со стандартным NT. Единственное изменение, обеспечивающее лучшую синхронизацию событий реального времени, внесено в часы. Так как в Windows NT имеются некоторые плохо предсказуемые процессы, то RTAPI позволит построить только мягкую СРВ с небольшим временем отклика, но недостаточно предсказуемую. Впрочем, большую часть непредсказуемости NT можно устранить, ограничив доступ к системному диску и сети.
Чтобы сделать NT более предсказуемой, необходимо прерывать ее внутренние задачи. В основе второй жесткой реализации RTX 4.1 лежит модификация HAL. В обеспечении детерминизма важную роль играют программируемые часы. В каждый тик часов - аппаратное прерывание с регулярными интервалами времени - предпочтение отдается задаче реального времени. Оставшееся время предоставляется процессам NT, в том числе и процессам мягкого реального времени. Чем чаще тикают часы, тем больше возможностей у процессора для выполнения задач реального времени. Необходимо добиться баланса между многими факторами: частота тиков, время, выделенное для обработки в реальном времени, время, выделенное для выполнения задач NT.
Простое решение здесь состоит в том, что NT выполняется на одной группе процессоров, а часть реального времени - на другой. Возможно применение архитектур параллельной шины с VMEbus, PCI, PMC или архитектур последовательной шины с Ethernet. Если необходимо, подсистемы могут быть связаны механизмом IPC и процедурами удаленного вызова. Преимущества такого решения:
Недостатки:
Чудес не бывает. Если вы хотите сохранить высокую совместимость с NT, то надо будет заплатить и более высокую цену. Если вы интересуетесь только частью интерфейса Win32 API, то можете работать с ОС РВ, имеющей этот интерфейс.
Имеется множество запросов на комбинации NT и РВ. Даже если это и не лучшее решение, рынок должен следовать желаниям заказчика. Разумеется, лучше всего было бы регулярное модифицировать саму Windows NT. Но пока компания Microsoft оставляет эту нишу свободной и она спонтанно заполняется производителями, зачастую использующими разные трюки, приводящие к несовместимости. Следует помнить, что использование трюков может в будущем привести к проблемам сопровождения.
Требование 1. ОС РВ должна быть многонитевой и допускать вытеснение (preemtible).
Предсказуемость достигается, если в ОС допускается много параллельных потоков управления (нитей), а диспетчер ОС может прервать выполнение любой нити (вытеснить ее) в системе и предоставить ресурсы той нити, которой они требуются в первую очередь. ОС и аппаратная архитектура также должны предоставлять множество уровней прерываний, чтобы вытеснение было возможно и на уровне прерываний.
Требование 2. Диспетчеризация должна осуществляться на базе приоритетов.
Основная сложность диспетчеризации заключается в том, чтобы обнаружить, какая именно нить нуждается в ресурсах в первую очередь. В идеале ОС РВ предоставляет ресурсы той нити или драйверу, которым осталось меньше всего времени до установленного срока. Чтобы сделать это, ОС должна знать, когда нить обязана завершить свою работу и сколько времени ей понадобится. Поскольку это очень трудно реализовать, таких ОС пока еще не существует. Поэтому механизм диспетчеризации потоков управления в современных ОС базируется на понятии приоритета: ресурсы предоставляются нити с наивысшим приоритетом.
Требование 3. Механизм синхронизации нитей должен быть предсказуемым.
Механизм захвата ресурсов и межнитевых связей необходим, поскольку нити разделяют общие ресурсы.
Требование 4. Должна существовать система наследования приоритетов.
Разделение нитями с разными приоритетами общих ресурсов может привести к классической проблеме инверсии приоритетов. Такая проблема возникает, если имеется по крайней мере три нити. Если нить с низшим приоритетом захватит ресурс, разделяемый с нитью высшего приоритета, тогда нить со средним приоритетом будет выполняться, а нить с высшим приоритетом будет приостановлена до тех пор, пока захваченный ресурс не освободится, что произойдет только тогда, когда нить с низшим приоритетом получит управление и завершит работу, связанную с захваченным ресурсом. В этом случае время, необходимое для завершения нити с высшим приоритетом, зависит от нити с низшим приоритетом. Этот случай называется инверсией приоритета. Ясно, что в такой ситуации трудно уложиться в заранее установленный лимит времени.
Чтобы избежать этого, ОС РВ должна допускать "наследование" приоритета, подталкивая нить с низшим приоритетом. Наследование приоритета означает, что блокирующая нить наследует приоритет нити, которую она блокирует (конечно, только если последняя обладает более высоким приоритетом).
Требование 5. Временные характеристики ОС должны быть предсказуемы и известны.
Разработчик СРВ должен знать, сколько времени затрачивается на ту или иную системную работу. Кроме того, должны быть известны уровни системных прерываний и уровни IRQ (линий запросов прерываний) драйверов устройств, максимальное время, которое они затрачивают и т.п.