7.4.1 Интерфейс приложения реального времени (RTAI)

Предыдущая  Содержание  Следующая V*D*V

RTAI (Real-Time Application Interface, Интерфейс Приложения Реального Времени) является расширением реального времени для Linux с открытым исходным кодом. Ядро RTAI представляет собой уровень абстрагирования оборудования (hardware abstraction layer, HAL) поверх которого может работать Linux и ядро жёсткого реального времени. HAL предоставляет механизм для улавливания прерываний от периферии и направляет их в Linux только если они не нужны для какой-либо обработки в режиме жёсткого реального времени. В рамках RTAI задача жёсткого реального времени может быть создана и запланирована с использованием интерфейсов RTAI. Для планирования задач реального времени RTAI использует свой собственный планировщик. Этот планировщик отличается от встроенного планировщика Linux. Для взаимодействия с другими задачами реального времени или обычными процессами Linux задача реального времени может использовать механизмы IPC, предоставляемые RTAI.

 

Для задач, запланированных в рамках RTAI, мы используем термин "задача реального времени", если не указано иное.

 

Архитектуру системы Linux на основе RTAI показывает Рисунок 7.6. (Для простоты мы не показали на схеме задачи LXRT.) Детали этой диаграммы станут понятны в следующий параграфах.

 

Рисунок 7.6 Архитектура RTAI.

Рисунок 7.6 Архитектура RTAI.

 

RTAI поддерживает несколько архитектур, такие как x86, ARM, MIPS, PowerPC, CRIS, и другие. Модули RTAI, такие как планировщик, IPC, и так далее, не выполняются в отдельном адресном пространстве. Они реализованы в виде модулей ядра Linux; таким образом, они выполняются в адресном пространстве Linux. Не все модули ядра должны присутствовать всегда; основным модулем является rtai и он должен присутствовать всегда, а другие модули могут быть загружены динамически, когда это требуется. Например, rtai_fifo реализует функциональность FIFO RTAI и должен быть загружен только если требуется такая функциональность.

 

HAL

 

HAL перехватывает все аппаратные прерывания и направляет их либо стандартному Linux, либо задачам реального времени, в зависимости от требований планировщиков RTAI. Прерывания, предназначенные для запланированных в реальном времени задач, направляются непосредственно в такую задачу, в то время как прерывания, не требуемые какими-либо запланированными задачами реального времени, отправляются Linux. Таким образом, HAL предоставляет основу, на которую смонтирован RTAI, с возможностью полностью контролировать прерывания от периферии и вытеснять Linux. В RTAI существуют две реализации HAL:

 

RTHAL (Real-Time Hardware Abstraction Layer, Уровень Абстрагирования Оборудования Реального Времени): он заменяет таблицы дескрипторов прерываний Linux своей таблицей для перехвата прерываний периферии.

ADEOS: В этой модели RTAI является более высокоприоритетным доменом, чем Linux.

 

Планировщики

 

Дистрибутив RTAI включает в себя четыре различных вытесняющих планировщика реального времени, работающих на основе приоритетов.

 

UP: планировщик, предназначенный для однопроцессорных платформ.

SMP: предназначен для машин с симметричной многопроцессорной обработкой.

MUP: предназначен для многопроцессорных машин без симметричной многопроцессорной обработки.

NEWLXRT: он объединяет три вышеописанных планировщика и может планировать задачи Linux и потоки ядра наряду с задачами RTAI ядра, расширяя таким образом интерфейс приложения жёсткого реального времени для задач Linux и потоков ядра.

 

Планировщики UP, MUP и SMP могут планировать только задачи RTAI ядра.

 

LXRT

 

Все задачи реального времени, запланированные под RTAI, работают в адресном пространстве ядра. Приложения RTAI загружаются как модули ядра. Первой функцией, которую они вызывают, является rt_task_init. rt_task_init создаёт задачу реального времени RTAI, которая становится запланированной планировщиком RTAI. Эта задача теперь может использовать все службы реального времени RTAI.

LXRT предоставляет службы RTAI реального времени в пространство пользователя. Таким образом, интерфейс RTAI может вызвать любой обычный процесс Linux. Это очень мощный механизм, который устраняет разрыв между задачами реального времени RTAI и обычными процессами пользовательского пространства Linux. Когда процесс Linux вызывает rt_task_init, LXRT создаёт задачу ядра RTAI, которая действует как представитель процесса Linux. Этот представитель запускает службы RTAI от имени процесса Linux. Например, если процесс Linux вызывает rt_sleep, этот представитель выполнит эту функцию под управлением планировщика RTAI. Когда этот представитель возвращается из rt_sleep, управление возвращается процессу Linux.

 

IPC

 

RTAI поддерживает несколько механизмов IPC, которые могут использоваться для взаимодействия между задачами RTAI–RTAI и процессами RTAI–Linux. Они перечислены в Таблице 7.13.

 

Таблица 7.13 Механизмы IPC RTAI

 

IPC

Описание

Модуль ядра

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

Используются для синхронизации задач при появления нескольких событий. Их использование аналогично использованию семафоров, за исключением того, что сигнал и операция ожидания зависят не от счётчика, а от набора событий, которые могут произойти.

rtai_bits.o

FIFO

Обеспечивают взаимодействие между  приложениями пользовательского пространства Linux и задачами RTAI пространства ядра.

rtai_fifos.o

Совместно используемая память

Модуль позволяет совместно использовать память между задачами RTAI и процессами Linux.

rtai_shm.o

Семафоры

Семафоры RTAI поддерживают наследование приоритетов.

rtai_sem.o

Почтовый ящик (Mailbox)

Очень гибкий механизм IPC. Он может быть использован для отправки сообщений переменной длины между Linux и RTAI. RTAI также поддерживает типизированные почтовые ящики для широковещательной передачи сообщений и срочной доставки сообщений.

rtai_mbx.o, rtai_tmbx.o(типизированный mailbox)

NetRPC

Механизм передачи сообщений между задачами, который расширяет RTAI для работы в распределённом окружении.

rtai_netrpc.o

Pqueue

Pqueue RTAI реализует интерфейсы очереди сообщений POSIX 1003.1b.

rtai_mq.o

 

Модули разного назначения

 

RTAI также предоставляет следующее:

 

malloc реального времени (rtai_malloc): RTAI обеспечивает реализацию malloc() для режима реального времени. Задача RTAI можно смело выделять или освобождать память без какой-либо блокировки. Это достигается путём выделения памяти  в режиме реального времени из заранее выделенной памяти в глобальной "куче".

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

Pthread (rtai_pthread): поддерживают потоки POSIX.1c (в том числе мьютексы и условные переменные).

Сторожевой таймер (rtai_wd): этот модуль защищает RTAI и Linux от ошибок программирования в приложениях RTAI.

Xenomai: данная подсистема обеспечивает плавный переход от патентованной операционной системы (например, VxWorks, pSOS и VRTX™) к RTAI.

Драйверы режима реального времени: RTAI предоставляет драйверы реального времени последовательной линии и параллельного порта. Также поддерживается интерфейс драйвера устройства comedi. Проект comedi разрабатывает драйверы, наборы программ и библиотеки для карт сбора данных с открытым исходным кодом (http://www.comedi.org/).

 

Написание приложений RTAI

 

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

Задача RTAI, работающая как модуль ядра, состоит из трёх частей:

 

Функция module_init: эта функция вызывается при загрузке модуля (с использованием insmod или modprobe). Следует выделить необходимые ресурсы, создать задачу реального времени и запланировать её выполнение.

Код, относящийся к задаче реального времени: он состоит из различных процедур, которые реализуют функциональность задачи реального времени.

Функция module_cleanup: эта функция вызывается всякий раз, когда модуль ядра выгружается. Она должна уничтожить все выделенные ресурсы, остановить и удалить задачу реального времени, и тому подобное.

 

Структура задачи RTAI в виде модуля ядра показана в Распечатке 7.13. В этом примере мы создаём периодическую задачу, которая печатает "Hello Real-Time World".

Как уже упоминалось, LXRT экспортирует интерфейсы RTAI в пространство пользователя. Для поддержки этого LXRT требует от задачи пользовательского пространства использовать политику планирования SCHED_FIFO с блокировкой всей их памяти (с помощью системного вызова mlockall). LXRT предлагает следующие преимущества по сравнению с задачей RTAI, работающей как модуль ядра:

 

Для отладки LXRT задачи реального времени можно использовать средства отладки пользовательского пространства.

Задачи LXRT реального времени подчиняются механизму защиты памяти Linux. Таким образом, ошибка в задаче не вызовет падение всей системы.

Поскольку нет зависимости от ядра, задача может поставляться только в двоичном виде, без предоставления исходного кода.

Для запуска задачи вам не нужно иметь права суперпользователя (эта поддержка осуществляется через интерфейс rt_allow_nonroot_hrt).

 

Чтобы проиллюстрировать структуру задачи реального времени LXRT пользовательского пространства, мы ещё раз написали наш пример "Hello Real-Time World". Пожалуйста, обратитесь к Распечатке 7.14.

 

Предыдущая  Содержание  Следующая