+7 (812) 507-6236
Обратная связьEnglish
Главная → Статьи → Системное ПО → Статья #32. Миграция Nucleus SE: Нереализованные функции и совместимость
Версия для печати

Статья #32. Миграция Nucleus SE: Нереализованные функции и совместимость

4 сентября 2019

Основным требованием при разработке Nucleus SE была высокая степень совместимости с Nucleus RTOS. Nucleus SE поддерживает определенную часть функционала Nucleus RTOS, о чем уже не раз говорилось в предыдущих статьях. В этой статье собраны ключевые отличия двух систем. Сам автор говорит, что задумывал эту статью как краткий справочник для всех, кто собирается переходить с одного ядра на другое, либо находится в процессе выбора ядра для определенного проекта.




Статья #32. Миграция Nucleus SE: Нереализованные функции и совместимость.


Помимо ограниченного или упрощенного функционала, по сравнению с Nucleus RTOS, Nucleus SE также разрабатывалась с упором на максимально эффективное использование памяти с широкими возможностями пользовательской настройки. Важной частью такого подхода является масштабируемость. Многие особенности функционала ядра могут быть активированы или отключены по необходимости. Очевидно, отключение функционала в конкретной реализации увеличивает ее несовместимость с Nucleus RTOS.

В Nucleus RTOS система может быть создана с неопределенным количеством объектов ядра, единственным ограничением здесь выступает количество доступных ресурсов (то есть памяти). Nucleus SE имеет ограничение в шестнадцать объектов каждого типа; система может иметь от одной до шестнадцати задач и от нуля до шестнадцати объектов каждого типа (почтовые ящики, очереди и т.д.). Несмотря на то, что этот лимит может быть увеличен, потребуются значительные усилия, так как в Nucleus SE широко используется возможность хранения индекса объекта в полубайте (четыре бита). Кроме того, при более чем шестнадцати задачах планировщик приоритетов (Priority), скорее всего, станет очень неэффективным. Приложение, функционал которого серьезно страдает от данных ограничений, не подходит для Nucleus SE, в данном случае Nucleus RTOS является гораздо более подходящим выбором.


Планировщик


Как и все современные ядра реального времени, Nucleus RTOS имеет очень гибкий планировщик, который обеспечивает несколько уровней приоритета (с неопределенным количеством задач на каждом уровне приоритетов), а также предоставляет возможность выбора планировщика Round Robin и Time Slice. Nucleus SE гораздо проще и предлагает четыре планировщика, которые должны быть выбраны во время сборки: Run to Completion, Round Robin, Time Slice и Priority (планировщик приоритетов). Комбинировать разные планировщики нельзя (то есть составного планировщика нет). Например, нельзя выбрать комбинацию планировщиков Time Slice и Priority. Кроме того, планировщик Priority позволяет назначать только одну задачу на каждый уровень приоритета, то есть существует столько же уровней приоритета, сколько и задач. Приоритет задачи задается во время сборки и больше не меняется (как и слот времени, если выбран планировщик Time Slice).


Вызовы API


Программный интерфейс приложения (API) – видимое «лицо» операционной системы. Неудивительно, что именно здесь отличия между Nucleus RTOS и Nucleus SE наиболее очевидны.

API Nucleus SE отличается от API Nucleus RTOS. Однако API Nucleus SE тщательно проработан, чтобы его можно было перенести на фрагмент Nucleus RTOS API. Обладатели лицензионной Nucleus RTOS могут получить «оболочку» (заголовочный файл, содержащий макросы #define), которая выполнит перенос практически напрямую.

Из того, что Nucleus SE API можно назвать «подмножеством» Nucleus RTOS API, следует, что некоторые вызовы API в нем отсутствуют. Это действительно так и это является неизбежным результатом критериев разработки Nucleus SE. В некоторых вызовах API просто нет смысла, так как они связаны с несуществующим функционалом, другие вызовы были исключены ради упрощения реализации некоторых объектов ядра. Все это подробно описано в следующих разделах этой статьи.


Общие функции API


В Nucleus RTOS существуют функции API, которые являются общими для нескольких различных типов объектов ядра либо даже для всех типов объектов. Некоторые из них были реализованы и в Nucleus SE, хорошим примером такой функции является reset. Другие же функции неприменимы к реализации объектов ядра в Nucleus SE.


Создание и удаление


В Nucleus RTOS все объекты ядра динамические, они создаются и удаляются по мере необходимости. Следовательно, для этого имеются вызовы API. В Nucleus SE все объекты статические (они создаются во время сборки), поэтому такие вызовы API не нужны.


Возвращение указателей на объекты


Главным идентификатором (дескриптором) объектов ядра в Nucleus RTOS является указатель на блок управления объекта, который назначается при создании объекта. Следовательно, существует и набор вызовов API, которые возвращают список указателей на объекты каждого типа. Так как Nucleus SE использует простой индекс для идентификации объектов ядра, в таких вызовах нет необходимости. Программа может опросить ядро, чтобы узнать, сколько экземпляров объектов конкретного типа сконфигурировано (используя вызов наподобие NUSE_Mailbox_Count()); если это значение равно n, индексы объектов этого типа будут иметь значения от нуля до n-1.


Трансляция данных

Для некоторых типов объектов ядра Nucleus RTOS (например, почтовых ящиков, очередей и каналов) предоставляется служебный вызов API для трансляции данных. Это позволяет отправлять данные на каждую задачу, которая ожидает данных от объекта. Такая возможность была исключена из Nucleus SE для упрощения, так как доступ к данным таких объектов всегда выполняется в контексте конкретной задачи, которая затем освобождает объект. Следовательно, для реализации трансляции бы потребовался дополнительный механизм флагов.

Уникальные функции API объектов


Многие объекты ядра имеют вызовы API, уникальные для конкретного типа объектов и отличающиеся в Nucleus RTOS и Nucleus SE.


Задачи


Так как планировщик Nucleus RTOS значительно сложнее, чем в Nucleus SE, в некоторых функциях API нет необходимости:


  • Изменение положения прерывания задачи – не поддерживается в Nucleus SE.
  • Изменение приоритета задачи – в Nucleus SE приоритет задачи назначается во время конфигурации и не может быть изменен.
  • Изменение слота времени задачи – в Nucleus SE значение слота времени общее для всех задач и задается во время конфигурации.
  • Завершение задачи – в Nucleus SE состояние задач «завершена» не поддерживается.

Динамическая память


Так как в Nucleus SE все создается статически, динамическая память не поддерживается (и не требуется). Следовательно, в связанных с этим функциях API также нет необходимости.


Сигналы


Nucleus RTOS поддерживает обработчики сигналов, программы, которые запускаются (подобно обработчикам прерывания), когда сигналы задач изменяются. Эта возможность была исключена из Nucleus SE, следовательно, вызовы API для управления сигналами и создания обработчика сигналов не требуются.


Прерывания


В Nucleus SE используется подход «невмешательства» в прерывания, просто предоставляя возможность выполнять некоторые вызовы API из обработчика прерывания. Следовательно, некоторые вызовы Nucleus RTOS API, которые указывают, как ядро должно обрабатывать прерывания, не поддерживаются.


Диагностика


Nucleus SE имеет очень скромные службы диагностики, следуя своему «сдержанному» стилю разработки, ограничиваясь (опциональной) проверкой параметров и выводом кода версии продукта. Следовательно, вызовы Nucleus RTOS API, связанные с ведением журнала истории и подтверждением отсутствия ошибок, не поддерживаются.


Драйверы


Nucleus RTOS имеет четко определенную формальную структуру драйверов и несколько функций API, связанных с управлением драйверами. Nucleus SE не имеет такой структуры, следовательно, в соответствующих вызовах API нет необходимости.


Функционал вызовов API


Некоторые аспекты функционала Nucleus SE, которые реализованы в упрощенном виде, приводят к отличиям от Nucleus RTOS. Некоторые из них влияют на то, как используются вызовы API и на доступные службы.


Таймауты


При использовании Nucleus RTOS часто случаются ситуации, когда вызов API может приостановить задачу, ожидающую доступа к ресурсу: задача блокируется. Такая приостановка задачи может быть неявной (то есть до тех пор, пока ресурс не станет доступным), либо может быть указано значение таймаута. Nucleus SE предоставляет блокировку вызовами API в виде опции, однако может быть использована только неявная приостановка (то есть вызов может использовать только NUSE_SUSPEND или NUSE_NO_SUSPEND, а не значение таймаута). Такую возможность достаточно просто добавить в Nucleus SE.


Порядок приостановки


Когда в Nucleus RTOS создаются несколько типов объектов, может быть назначен порядок приостановки. Это последовательность, в которой несколько заблокированных задач будут возобновляться по мере появления ресурсов. Доступны два варианта: FIFO, первым пришел – первым ушел (first in first out), при котором задачи возобновляются в том же порядке, в котором блокируются; либо по приоритету, при котором задача с наивысшим приоритетом всегда возобновляется первой. Nucleus SE не предлагает такого выбора. В ней реализован только порядок по приоритету. На самом деле, правильнее говорить порядок по индексу задачи, так как порядок приостановки можно применять не только при использовании планировщика Priority, но и в случае использования планировщиков Round Robin и Time Slice.


Уникальный функционал объектов

В некоторых случаях были необходимы изменения функционала, связанные с определенными типами объектов.

Обработчики сигналов

Как уже было сказано выше, реализация сигналов в Nucleus SE не поддерживает процедуры обработки сигналов.


Параметры таймера приложения

Таймер имеет начальную длительность/первоначальную длительность работы и длительность перезапуска и может опционально выполнять заданную пользователем функцию при завершении. Такой функционал поддерживается как в Nucleus RTOS, так и Nucleus SE. Однако Nucleus SE, в отличие от Nucleus RTOS, не позволяет менять описанные выше параметры при вызове функции API для сброса. Кроме того, в Nucleus SE вся поддержка процедур завершения таймеров опциональна.


Флаги событий

В Nucleus RTOS существует опция для «поглощения» флагов событий. Это значит, что флаги, которые соответствуют заданным задачей критериям, сбрасываются. Такой функционал не поддерживается в Nucleus SE, так как возможность поиска соответствий критериям нескольких задач значительно повышает сложность системы.


Размеры данных


Два критерия разработки Nucleus SE: поддержание простоты и минимизация использования памяти, привели к определенным отличиям в размерах элементов данных по сравнению с Nucleus RTOS. Стоит заметить, что Nucleus RTOS обычно использует данные типа unsigned, который, скорее всего, 32-битный. в то время как Nucleus SE использует рационализированные типы данных, например U32, U16, U8 и так далее. (Примечание переводчика: На мой взгляд, автор прав для 8-битных систем. В современных системах регистры всё равно 32 битные, поэтому отрезание старшей части тратит память на код и такты на его исполнение, а данные всё равно выравниваются на 32 бита при хранении в памяти, иначе упадёт быстродействие системы. Так что выигрыша такой подход для современных систем не даёт, а проигрыш из-за добавленных компилятором команд, отрезающих старшую часть, – вполне может.).


Почтовые ящики


В Nucleus RTOS почтовый ящик хранит сообщение, состоящее из четырех элементов данных типа unsigned. В Nucleus SE почтовый ящик хранит элемент данных типа ADDR. По моему мнению, почтовые ящики часто используют для передачи адреса (указывающего на определенные данные) от задачи к задаче.


Очереди


В Nucleus RTOS очередь обрабатывает сообщения из одного или нескольких элементов данных типа unsigned. Очередь также может быть настроена на обработку сообщений переменной длины. В Nucleus SE очередь обрабатывает сообщения, состоящие из одного элемента данных типа ADDR. По моему мнению, очереди используются похожим образом с почтовыми ящиками. Кроме того, в Nucleus RTOS общий размер очереди (т.е. общее количество беззнаковых элементов, которое можно поместить в очередь) указывается как значение типа unsigned. В Nucleus SE это значение имеет тип U8. Следовательно, очередь может вмещать меньше данных.


Каналы передачи данных


В Nucleus RTOS канал обрабатывает сообщения из одного или нескольких байтов; канал также может быть настроен на обработку сообщений переменной длины. В Nucleus SE канал обрабатывает сообщения, состоящие из одного или нескольких элементов данных типа U8. Размер сообщения задается во время настройки для каждого канала. Кроме того, в Nucleus RTOS общий размер канала (то есть общее количество байт, которое можно поместить в канал) указывается как значение типа unsinged. В Nucleus SE это значение имеет тип U8 и представляет количество сообщений (в вызове API NUSE_Pipe_Information()). Следовательно, канал может вмещать меньше данных.


Группы флагов событий


В Nucleus RTOS группа флагов событий содержит 32 флага; в Nucleus SE их количество уменьшено до восьми. Этот размер был выбран так как вероятные целевые процессоры Nucleus SE могут эффективно обрабатывать 8-битные данные. При этом, изменить количество флагов в группах флагов событий, обрабатываемых Nucleus SE, будет несложно.


Сигналы


В Nucleus RTOS каждая задача имеет набор из 32 сигнальных флагов. В Nucleus SE сигналы опциональны, и каждая задача имеет набор из 8 флагов. Этот размер был выбран, так как вероятные целевые процессоры Nucleus SE могут эффективно обрабатывать 8-битные данные. При этом, изменить количество флагов в наборах флагов сигналов, обрабатываемых Nucleus SE, будет несложно.


Разделы памяти


В Nucleus RTOS количество и размер разделов имеют тип unsigned. В Nucleus SE количество разделов – параметр типа U8, а размер раздела – U16. Это приводит к некоторым ограничениям размера раздела и пула.


Таймеры


В Nucleus RTOS таймеры (как таймеры приложения, так и таймеры сна задачи) работают со значениями типа unsigned. В Nucleus SE они имеют тип U16. Этот тип был выбран, так как вероятные целевые процессоры Nucleus SE могут эффективно обрабатывать 16-битные данные (а восьми бит для использования таймера явно недостаточно). При этом, изменить размер таймеров в Nucleus SE будет несложно.

В следующей статье будет рассматриваться как Nucleus SE может быть использована в проекте встраиваемого программного обеспечения.


Об авторе: Колин Уоллс уже более тридцати лет работает в сфере электронной промышленности, значительную часть времени уделяя встроенному ПО. Сейчас он – инженер в области встроенного ПО в Mentor Embedded ( подразделение Mentor Graphics). Колин Уоллс часто выступает на конференциях и семинарах, автор многочисленных технических статей и двух книг по встроенному ПО. Живет в Великобритании. Профессиональный блог Колина: https://blogs.mentor.com/colinwalls/, e-mail: colin_walls@mentor.com


Источник: https://www.embedded.com/design/operating-systems/4461896/Nucleus-SE-migration--Unimplemented-facilities-and-compatibility

Теги: ОСРВ, RTOS, встроенное ПО, служебные вызовы, API.