Маленькие ОС для маленьких устройств

17 декабрь, 2004 - 00:00Андрей Зубинский Казалось бы, зачем крохотному специализированному вычислителю, реализованному в виде одной микросхемы со сравнительно небольшим числом выводов и решающему строго ограниченный перечень задач, может понадобиться операционная система? Вот, например, контроллеру микроволновой печи? На первый взгляд, вся-то его работа заключается в выполнении примитивных действий. Он выявляет нажатия кнопок (или в более общем случае -- изменения положения органов управления), проверяет состояние скрытых от пользователя критически важных механизмов (в частности -- электрических контактов, механически связанных с экранирующей СВЧ-излучение дверцей). Кроме того, на контроллер возложены задачи формирования временных интервалов и, естественно, -- выдачи команд на различные исполнительные устройства (блок питания СВЧ-генератора и электромагнитный замок, предотвращающий открывание дверцы печки при ее работе). На первый взгляд, все элементарно. Но это только на первый взгляд -- мы еще вернемся к "примитивным действиям", но чуть позже...

Обыкновенно весь этот (по большому счету -- совершенно неполный) перечень задач возлагается на один специальный вычислитель. Во-первых, производитель массовой продукции считает каждый цент и стремится выжать из способностей микроконтроллера по-максимуму. Во-вторых, такая концентрация решаемых одним функционально законченным устройством задач дает существенное повышение надежности. В-третьих, у производителя появляется возможность на базе одной модели продукта создавать целый модельный ряд с различной функциональностью только благодаря изменениям "прошивки" скрытых вычислителей (естественно, для микроволновок, у которых главная составляющая функциональности определяется все-таки неэлектронными возможностями, это не столь важно, но разработчики мобильных телефонов такой прием просто обожают). В итоге от применения "умной начинки" выигрывают все -- потребитель получает более дешевые и функционально разнообразные устройства, производитель -- более перспективную и привлекательную "платформу" с довольно высокой надежностью (это весьма немаловажно -- высокая надежность существенно снижает затраты на сопровождение изделия в период его жизненного цикла).

Вас ничего не смущает в только что нарисованной картине? Ну, например, изобилие эпитетов, придающих ей какой-то лубочно-идиллический характер -- примитивно, элементарно, надежно, функционально, привлекательно? Все кажется настолько красивым, что пора доставать большую ложку дегтя...

Возможно, в некотором абсолютно идеальном мире, населенном совершенными существами и подчиненном строго детерминированным трем (даже лучше -- двум... три -- это очень много) законам, упомянутая идиллия действительно ничем бы не омрачалась. Совершенный пользователь был бы образцово внимателен и, прочитав раз инструкцию (он же совершенный пользователь, а значит, инструкции он читает ко всему), не только запомнил бы ее на всю жизнь, но и неукоснительно, автоматически выполнял бы ее требования всегда, в любой обстановке (хотя какая "любая обстановка" может быть в идеальном мире). Совершенные рабочие на идеальном заводе на идеально точных станках из незнающих износа материалов производят абсолютные конструкции. Совершенная окружающая среда не допускает никаких отклонений условий эксплуатации от идеальных. Ну и так далее... Увы, в реальности все совершенно не так. Мало того, что реальные пользователи никогда не читают никаких инструкций, -- они тут же (или по одной из N+1 возможных или невозможных причин, где N -- любое названное вами число) норовят нарушить все мыслимые и немыслимые правила. Рабочие на заводах, где введены самые изощренные процедуры контроля качества, стремятся сделать все не так, очевидно наилучшие материалы для конструктивов, титан и алмаз, почему-то практически никогда не применяются. Окружающая среда преподносит самые неожиданные сюрпризы -- то электричество отключают "веерным" методом, то почему-то хотят использовать устройство рядом с линией электропередачи, то срочно надо его включить в грозу. Все эти тонкие нюансы превращают жизнь разработчика программ для компьютеров-невидимок в сущий ад. Но есть один особенный фактор реальности, о котором мы старательно умалчивали. Это, естественно, время. "Особенность" времени можно легко понять, если сделать одно важное уточнение -- все перечисленные (и еще N+1 неперечисленных, N -- опять любое нравящееся вам число) факторы в реальном мире имеют свойство проявляться одновременно. User vulgaris (пользователь обыкновенный) непременно начнет открывать дверцу микроволновки именно тогда, когда кратковременно пропадет электричество, при этом большинство таких попыток будет предприниматься в грозу, а у стареньких микроволновок -- участников такого немыслимого в совершенном мире действа непременно износится какая-нибудь важная пластмассовая деталька электромагнитного замка. То есть одновременно случится все, что может случиться, и еще кое-что, что случиться ну никак не может.


"Одновременность", или Время и реальное время

Упомянутая "одновременность", если ее воспринимать максимально прямолинейно, -- явление как раз присущее идеальному миру. Именно его и только его можно назвать "совершенная одновременность" -- когда о нескольких событиях с уверенностью говорится, что они произошли "в определенный момент времени", или, более точно, на протяжении бесконечно малого интервала времени. В реальном мире такие бесконечно малые интервалы встречаются, мягко говоря, нечасто, что, по сути, означает отсутствие каких-либо общих количественных оценок одновременности событий. Вместо них принято пользоваться оценкой качественной -- "реальностью" времени.

Термин "реальное время" с некоторых пор употребляется настолько часто и в таких разнообразных контекстах, что отыскание какого-либо его точного толкования -- задача не из простых. Например, в стандарте POSIX 1003.1 (один из семейства стандартов, определяющих интерфейсы мобильной операционной системы) для "реального времени" дается следующее определение: "...способность ОС обеспечить требуемый уровень сервиса в заданном интервале времени". Заметьте, что ни о конкретном значении интервала (секунда, минута, час, день...), ни о каких показателях "уровня сервиса" и речи не идет. Такая общность, доведенная практически до невнятности, многих не устраивает -- в первую очередь системных архитекторов и программных инженеров (software engineers), работающих в области встраиваемых систем (embedded systems). И если мы собираемся бегло обозреть некоторые доступные операционные системы для встраиваемых вычислителей, уточнения терминологии нам не избежать. Увы, речь идет именно о терминологии, а не об одном термине "реальное время" или "система реального времени".

С точки зрения программного инженера системой является нечто, отображающее множество входов на множество выходов. Принципы, лежащие в основе этого отображения, формируют поведение (behaviour) системы. А реализация этих принципов требует определенного времени (естественно, если упомянутое "нечто" основывается на возможностях цифрового вычислителя с неидеальными характеристиками), что означает: реакция системы -- изменение состояний выходов, наступит с некоторой задержкой после изменения состояния ее входов. Это время задержки принято называть "временем отклика системы" (system response time). Типовые значения порядка времени отклика распространенных систем реального времени для разных областей применения таковы: для радио- и акустической локации -- микро- и миллисекунды; для логистики и складского учета -- секунды; для торговых операций -- минуты; для управления производственными процессами -- широкий диапазон от миллисекунд до минут; для управления химическими реакциями -- от минут до часов. Время отклика системы и поведение -- это то, от чего отталкивается разработчик, одни из главных требований к ней. Нормально функционируя, она, естественно, должна отвечать всем необходимым критериям. Состояние, в котором наблюдается несоответствие одному или более требований к ней, называется неисправностью, а такая система -- неисправной (failed system). Вот теперь, наконец, мы вооружились всеми нужными толкованиями, позволяющими дать определение "системе реального времени" (СРВ). СРВ -- это система, принципиальная работоспособность которой зависит не только от правильной реализации поведенческих механизмов, но и соблюдения требований ко времени отклика; в случае любого их несоблюдения система считается неисправной. Различают два основных типа СРВ -- "с сильной реальностью времени" (hard realtime) и со "слабой реальностью" (soft realtime). Критерием различия является плата за риск неисправности системы -- если она очень высока (или вообще запредельна) и заключается в утрате функциональности управляемой CPB, то речь идет о "сильной реальности", если же с ней можно смириться (управляемая система только теряет производительность), то, естественно, говорится о "слабой реальности времени". Чтобы было понятнее, неисправность системы реального времени в области авионики (управляющей электроники в авиации) в большинстве случаев приводит к катастрофическим последствиям. Равно как и неисправность управляющего программно-аппаратного комплекса атомной электростанции. Это cферы с явно "сильной реальностью времени".


Доступные микроОС

Возвращаясь к заданному в самом начале статьи вопросу, мы теперь можем найти на него ответ. Конечно, микровычислителю никакая операционная система не нужна. Но разработчику СРВ в большинстве случаев -- просто необходима. Без ее использования программисту встраиваемой системы придется многократно изобретать велосипед, самостоятельно реализуя ряд классических конструкций, фактически -- создавая собственную микроОС.

Естественно, сейчас можно было бы привести обзор лучших из существующих систем реального времени, но мы так не поступим. Во-первых, отличные коммерческие продукты обычно недоступны для желающих с ними "поиграться". Во-вторых, в силу определенных причин эти системы достаточно сложны (их производители стремятся удовлетворить запросы большого числа потребителей) и совершенно не годятся к использованию ни в качестве "учебной парты", ни как основа для какой-либо самоделки. Не пойдем мы и по другому возможному пути -- обозрению доступных свободно распространяемых операционных систем в микроисполнении. Их более чем достаточно, и это изобилие как раз свидетельствует в пользу высказанного ранее соображения -- многие разработки своим появлением обязаны как раз попытке программистов... не использовать операционную систему. Соответственно, качество документации таких систем крайне низкое. Но у такого изобилия есть и свои положительные стороны -- можно выбрать действительно несложные, отработанные программы с великолепными документациями. Именно о них мы и поговорим.

Первая система, весьма привлекательная для всех желающих не просто изучить устройство микроОС реального времени, а попробовать ее на деле, -- Tics. Метрики, демонстрирующие сложность системы, подтверждают ее пригодность для начинающих (всего 665 строк кода на C и 299 строк объявлений и т. п. в заголовочном файле), а вот качество документации просто поражает -- крохотная Tics сопровождается обстоятельной 156 страничной книгой "Введение в программирование реального времени с использованием ОС Tics" и 54 страничным руководством программиста. Это, впрочем, вполне объяснимо -- распространяемая сегодня на основе лицензии GPL Tics имеет очень давнюю коммерческую историю. Ну а за качество Tics можно не волноваться -- она применялась и NASA, и самыми известными аэрокосмическими компаниями.

По сути, Tics представляет собой реализованное на языке С мобильное ядро ОС реального времени. Система портирована для многих целевых платформ -- начиная с 8 битных микроконтроллеров и заканчивая 64 битными процессорами семейства MIPS. Решаемые Tics задачи являются фундаментальными в мире систем реального времени -- это поддержка мультизадачности, управление ресурсами, прерываниями и, наконец, синхронизация. Мультизадачность, прерывания и синхронизация -- главные составляющие поддержки "реальности времени". Управление прерываниями -- один из основных механизмов оповещения об изменении состояния входов. Мультизадачность позволяет отображать множество входов на выходы -- формировать поведение системы за счет выполнения отдельных задач (более точно, потоков) -- написанных на C функций. Синхронизация позволяет основывать поведение системы на временных интервалах, формировать их последовательности и т. д. Кроме этих базовых функций, ядро Tics обеспечивает разработчика механизмами взаимодействия между потоками с помощью подсистемы сообщений. В общем, Tics настолько хорошо документирована и реализована, что в каком-то избыточном описании не нуждается. ОС распространяется бесплатно, и при использовании ее в реальной конструкции не требует никаких отчислений (разве что лицензия GPL может смутить разработчиков встраиваемых компьютеров-невидимок).

Еще одна очень интересная система -- nesos (Nilsen Elektronikk finite State machine Operating System), также бесплатна и отлично документирована. Nesos -- довольно изящная система, полностью построенная на идеологии конечных автоматов (Finite State Machine, характеризующаяся конечным числом возможных состояний вычислительная модель, способная переходить из одного состояния в другое при управлении, зависящем от внешних воздействий). Конечный автомат nesos изменяет состояния системы посредством двух механизмов -- передачи сообщения процессу и собственно процесса. Процессы активируются ядром nesos только тогда, когда имеются адресованные им сообщения. Процессы реализуют поведение системы и изменяют состояния, т. е., окончательно формируют конечно-автоматную модель. К ее достоинствам относятся крайне низкая зависимость кода от аппаратных средств, отсутствие накладных расходов на поддержание отдельных ключевых ресурсов (областей памяти стека, параметров, локальных переменных) для разных процессов, снижение требований к инструментальным средствам -- в первую очередь к используемым компиляторам, которые не обязаны генерировать повторно входимый (reentrant) код. Но главное преимущество nesos (как и других систем, основанных на концепции конечных автоматов) кроется в самом принципе их работы -- так как процессы в них активируются только тогда, когда для этого есть причины и все необходимые данные, в подобных системах отсутствуют механизмы ожидания процессом события. Процесс здесь -- атомарная неблокируемая единица.

Как и Tics, nesos реализована на языке C, процессами здесь являются C-функции. Несмотря на сравнимый с Tics размер реализации (849 строк C-кода), nesos хоть и нечувствительна, но более требовательна к аппаратной платформе. Это расплата за высокую мобильность системы. Нижняя граница предпочтительных аппаратных средств для использования данной микроОС начинается на уровне 16 битного микроконтроллера с приличным объемом оперативной памяти.

И наконец, последний участник нашего короткого обзора -- ОС FreeRTOS. Это самая сложная из приведенных систем (порядка тысячи строк кода), распространяемая на основе лицензии GPL. Она очень мобильна (и в спектр поддерживаемых ею аппаратных средств входят практически все популярные 8 битные контроллеры), достаточно традиционна и функционально схожа с Tics. FreeRTOS позволяет использовать различные политики мультизадачности (с приоритетными прерываниями -- preemptive, кооперативную и так называемую "уступчивую", все эти политики "по косточкам" разобраны в сопровождающей ОС Tics книге). Приятное отличие FreeRTOS от Tics -- поставляемые в дистрибутиве готовые адаптации системы для разных инструментальных средств и целевых платформ.

Собственно, этих трех ярких разработок более чем достаточно для того, чтобы самостоятельно изучить целый раздел теории операционных систем -- "ОС реального времени".