Увеличение возможностей ОСРВ с помощью программных модулей


PDF версия

За счет умелого использования программных модулей и установки связи между ОСРВ и приложением можно добиться качественной работы в режиме реального времени, даже если ресурсы устройства ограничены.

В большинстве встраиваемых систем бытового, медицинского и промышленного назначения для эффективного взаимодействия с пользователем требуется поддержка режима реального времени. Связь по мобильному телефону, обработка ультразвукового изображения или видеоконтроль на производственной линии — во всех этих и многих других приложениях обработка входных данных и вывод конечной информации должны осуществляться очень быстро. Обычно в таких системах используется маломощный процессор с небольшим объемом памяти, достаточным для выполнения всех операций. Учитывая ограниченность ресурсов, для управления прикладными задачами и потоками, а также для обработки прерываний и обеспечения взаимосвязи между несколькими потоками и их синхронизации рекомендуется использовать операционные системы реального времени (ОСРВ).
Существует огромное разнообразие ОСРВ — от больших, как Wind River VxWorks, до самых компактных, как Express Logic ThreadX. Надежные ОСРВ обеспечивают функционал, приближенный к возможностям настольного компьютера. Компактные ОСРВ не позволяют быстро выполнять сложные процедуры, поэтому их возможности ограничены. Компактные ОСРВ применяются в качестве библиотеки служб, которые вызываются напрямую соответствующей командой приложения. Инфраструктура ОСРВ и службы планирования и связи помогают упростить реализацию этих команд (см. рис. 1).

 

Рис. 1. Вызов службы в компактной ОСРВ

В большинстве компактных ОСРВ код приложения непосредственно связан со службами ОСРВ, которые он использует. В итоге образуется единый исполнительный файл-образ с расширением .elf. Для вызова функции используются команды вызова, прописанные в программном интерфейсе операционной системы. Все служебные функции привязаны к приложению через библиотеки ОСРВ. При проектировании образ загружается в целевую память и запускается с нее. В готовом устройстве он записывается в ПЗУ и выполняется при включении устройства. Такой «монолитный» подход эффективен как по временным затратам, так и по занимаемой схемой площади, но ему не хватает гибкости. Для внесения изменений в приложение или ОСРВ требуется повторная компоновка программы и загрузка или запись всего образа в память. Это обычная процедура на стадии проектирования, однако для готового устройства она может создать некоторые ограничения.
Операционные системы для настольных ПК, такие как Windows и Linux, и более функциональные ОСРВ, такие как VxWorks и QNX, имеют сдвоенную архитектуру, разделенную на ОС и приложение. В них имеется резидентное ядро, содержащее все доступные для приложений службы ОС или сервисы, необходимые для других функций ядра и связанные в отдельный исполнительный файл.
Система загружается с ядра и работает непрерывно. Это своего рода основание для приложений, которые загружаются и выполняются динамично, т.е. во время работы. Как правило, подкачка страниц в память накопителей и обратно в настольных системах и разделение пользователей во встраиваемых системах обеспечивается файлом виртуальной памяти. Такой подход используется в мобильных устройствах, таких как iPhone Apple или iPad, где новые приложения можно скачать через беспроводную сеть. ОС работает непрерывно и обрабатывает пользовательский интерфейс, через который осуществляется выбор приложения. Выбранные приложения запускаются вместе с ОС на процессоре. Аналогично в системах на основе ОСРВ приложения отделены от ядра ОС и содержатся в виртуальной памяти.
Еще одной общей особенностью больших ОСРВ и настольных ОС является возможность динамической загрузки приложения во время работы системы. В архитектурах с выделением ядра процессор работает независимо от приложений. Для доступа к аппаратным ресурсам встраиваемой системы используются службы ОС. Большие ОСРВ используются в телекоммуникационной сфере, оборонной и аэрокосмической промышленности. Они обеспечивают высокую степень модульности системы и позволяют производить обновление без остановки работы.

Внутренние прерывания

Эти приложения не являются монолитными и не связываются с ОСРВ, поэтому доступ к службам ОСРВ происходит через внутренние прерывания. Внутреннее прерывание — это программное прерывание, которое генерируется при наступлении различных событий, в зависимости от архитектуры (см. рис. 2). Обычно они используются для обнаружения ошибок до того, как они распространятся, или для остановки системы в случае, если невозможно выполнить требуемую операцию. Примерами может служить деление на ноль или загрузка невыровненных данных. Внутреннее прерывание можно вызвать принудительно с помощью инструкции вызова программного прерывания swi.

 

Рис. 2. Конфигурация с несколькими выходными делителями

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

Динамическая загрузка

Для небольших ОСРВ необходимо эффективно реализовать динамическую загрузку приложений с помощью вызовов служб ОСРВ. Требуется интерфейс вызова службы, который поддерживает загрузку во время работы. Для реализации такой архитектуры в компактных ОСРВ используется структура «модуль приложения». Программные модули представляют собой наборы потоков приложения, не связанных с ядром, а реализованных в виде отдельного исполняемого файла, который загружается в целевую память. Модули обращаются к службам ядра менеджера модулей — агента в образе ядра, который загружает и инициализирует модули, а также обрабатывает запросы служб ОСРВ.
Потоки внутри модулей осуществляют вызовы служб точно так, как они делали бы это, если были бы непосредственно связаны с приложением. Внутри модуля вызовы обрабатываются по протоколу взаимодействия с менеджером модулей. Таким образом, механизм внутренних прерываний не используется, и дополнительная нагрузка при вызове служб невелика.
Менеджер модулей может быть только один, а ограничений на количество модулей, которые могут быть загружены одновременно, и на количество потоков в одном модуле не установлено. Таким образом, ядро ​находится в отдельной структуре исполнения, работает непрерывно и обслуживает запросы модулей.
Как показано на рисунке 3, для достижения максимальной эффективности потоки приложения могут быть связаны с ядром и храниться в целевой памяти как часть его исполняемого образа. Этот вариант позволяет избежать необходимости перезагружать модули, содержащие эти потоки, и предоставляет наиболее эффективный интерфейс, однако при таком подходе увеличивается размер файла образа ядра и остается меньше памяти для использования модулями. Кроме того, отсутствует возможность динамической замены потоков. Загружаемые приложения-модули позволяют ОСРВ динамически запускать дополнительные потоки приложения, не связанные с ядром. Функциональность системы увеличивается без дополнительных схемотехнических приемов.

 

Рис. 3. Связывание приложения с ядром

Этот метод позволяет также менять настройки и обновлять систему. Принцип загрузки модулей по требованию идеально подходит для случаев, когда размер кода приложения превышает объем доступной памяти (см. рис. 4), в случае, если требуется частичное обновление прошивки или когда новые модули могут быть добавлены после начала эксплуатации продукта.
Еще одно преимущество загрузки отдельных программных модулей заключается в том, что каждый модуль может разрабатываться отдельным специалистом. Это помогает более эффективно построить процесс проектирования.

 

Рис. 4. Выборочная загрузка модулей

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

 

Рис. 5. Обращение к внешней памяти

Загружаемые программные модули — это прорыв для компактных приложений. Они позволяют существенно расширить возможности приложения и повысить удобство обслуживания. Меры по защите памяти на уровне потоков позволяют избежать ошибок доступа, устраняя самую распространенную причину трудных для диагностики сбоев программы.

Литература
1. J. Carbone. Bring big system features to small RTOS devices with downloadable app modules//www.eetimes.com.

Оставьте отзыв

Ваш емейл адрес не будет опубликован. Обязательные поля отмечены *