FreeRTOS

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 01:50, 26 октября 2017.
FreeRTOS
FreeRTOS.jpg
FreeRTOS-multiple.png
Создатели: Richard Barry & FreeRTOS Team
Разработчики: Real Time Engineers Ltd[1]
Выпущена: 5 June 2012 года; 10 years ago (2012-06-05)[2]
Постоянный выпуск: 9.0.0 / 25 May 2016 года; 6 years ago (2016-05-25)
Состояние разработки: Активный
Написана на: Си
Операционная система: ARM (ARM7, ARM9, Cortex-M3, Cortex-M4, Cortex-A), Atmel AVR, AVR32, HCS12, MicroBlaze, Cortus (APS1, APS3, APS3R, APS5, FPF3, FPS6, FPS8), MSP430, PIC, Renesas H8/S, SuperH, RX, x86, 8052, Coldfire, V850, 78K0R, Fujitsu MB91460 series, Fujitsu MB96340 series, Nios II, Cortex-R4, TMS570, RM4x
Платформа: GCC
Размер дистрибутива: 4-9 килобайт
Локализация: Языков доступно: Английский
Тип ПО: Компактная ОС реального времени
Лицензия: Модифицированная GPL или «коммерческая».
Веб-сайт freertos.org

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

Используется на 35 микропроцессорных архитектурах под лицензией GNU GPL с дополнением, позволяющим разработчику присвоить модифицированный код операционной системы. Среди поддерживаемых процессоров есть следующие архитектуры:[Источник 1]

Основные характеристики FreeRTOS

  1. Планировщик FreeRTOS поддерживает несколько типов многозадачности (вытесняющую, кооперативную, гибридную)[3]
  2. Размер ядра FreeRTOS составляет всего 4–9 кбайт, в зависимости от типа платформы и настроек ядра.
  3. FreeRTOS написана на языке Си (исходный код ядра представлен в виде всего лишь четырех Си‑файлов), ассемблерные вставки минимального объема применяются лишь там, где невозможно применить Си из‑за специфики конкретной аппаратной платформы.
  4. Поддерживает задачи (tasks) и сопрограммы (co‑routines). Сопрограммы специально созданы для МК с малым объемом ОЗУ.
  5. Богатые возможности трассировки.
  6. Возможность отслеживать факт переполнения стека.
  7. Нет программных ограничений на количество одновременно выполняемых задач.
  8. Нет программных ограничений на количество приоритетов задач.
  9. Нет ограничений в использовании приоритетов: нескольким задачам может быть назначен одинаковый приоритет.
  10. Развитые средства синхронизации «задача – задача» и «задача – прерывание» (очереди, двоичные семафоры, счетные семафоры, рекурсивные семафоры, мьютексы)
  11. Мьютексы с наследованием приоритета.
  12. Поддержка модуля защиты памяти (Memory protection unit, MPU) в процессорах Cortex‑M3.
  13. Поставляется с отлаженными примерами проектов для каждого порта и для каждой среды разработки.
  14. FreeRTOS полностью бесплатна, модифицированная лицензия GPL позволяет использовать FreeRTOS в проектах без раскрытия исходных кодов.
  15. Документация в виде отдельного документа платная, но на официальном сайте в режиме on‑line доступно исчерпывающее техническое описание на

английском языке.

Средства поддержки многопоточного окружения

К ним относятся:[Источник 2]

  1. Очереди, для обмена данными между тасками, или ISR.
  2. Бинарные семафоры, и счетные семафоры для синхронизации с эвентами (прерываниями).
  3. Мьютексы, для совместного доступа к ресурсу (например, порт).
  4. Критические секции, для создания области кода, выполнение которой не может быть прервано планировщиком.

Механизм обмена данными между задачами

Вывод при выполнении двух программ
Реальный паттерн выполнения двух задач

Для этого в ОСРВ используются очереди, которые представляет собой набор элементов определенного размера. В качестве элемента может выступать любая переменная C (char, int …..). При записи элемента в очередь создается его побайтовая копия. Аналогично и при чтении. Очередь в ОСРВ базируется на принципе «первым вошел — первым вышел»(FIFO- first in first out). То есть последний записанный в очередь элемент последним будет и прочитан.[4]

Это делается для того, чтобы избежать ошибок типа: если планировщик отдаст управление Задаче 2 в тот момент, когда Задача 1 еще не восстановила значение глобальной переменной, то Задача 2 получит вместе исходного правильного значения переменной другое, находящееся в обработке Задачи 1, что приведет к потере значения переменной как таковой.

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

Бинарные семафоры

Семафор.png

Бинарные семафоры, могут использоваться для разблокирования таска (запроса), всякий раз, когда происходит какое-либо событие(например, нажатие кнопки). Этот происходит следующим образом: при попадании в ISR определенного прерывания, мы отдаем семафор, в результате таск, ожидающий семафора забирает семафор и выходит из разблокированного состояния для проведения каких-либо операций.

Счётные семафоры

При использовании семафоров обычно возникает следующая ситуация: Произошел какой-то эвент, который вызвал прерывание. -> ISR «отдает» семафор, т.е. разблокирует ожидающий семафор таск. -> Ожидающий таск «забирает» семафор. -> После исполнения нужного кода таск опять переходит в блокированное состояние, ожидая новых эвентов.

Данный алгоритм отлично работает, но только не на больших частотах. На больших частотах необходимо использовать счетные семафоры, которые, как правило, используют в 2-х случаях:

  1. Также для синхронизации с эвентами, но на больших частотах.
  2. Управление ресурсами. В данном случае, количество семафоров обозначает количество доступных ресурсов.

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

Мьюкенсы

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

Данная абстракция представляет собой своеобразный жетон, имея который, таск может иметь доступ к ресурсу, и который необходимо вернуть по окончанию работы с ресурсом, причем вернуть «жетон» может только тот таск, который его взял. Для создания мьютекса используется специальная API функция, которая возвращает созданный мьютекс, или NULL, если недостаточно памяти.[Источник 3]

Состояния программ

Самые простые создаваемые задачи всегда нуждаются в каких-то действиях (пусть даже пустых в виде цикла задержки), и в них обычно не нужно ожидать чего-либо. Поскольку такие задачи не ожидают никаких событий, то они всегда готовы войти в состояние Running. Такой тип задач с продолжающейся обработкой имеет ограниченное применение, потому что такую задачу можно создать только с самым низким приоритетом. Если же такая задача будет запущена не с самым низким приоритетом, то она не даст запуститься задачам с более низким приоритетом и возникнет состояние not running.[Источник 4]

Not running (не запущено)

Задача, управляемая событием, запускается в работу (делает обработку) только после возникновения переключающего состояние задачи события, и такая задача не может войти в состояние Running, пока такое событие не произойдет. Шедулер (принимает решение о переводе задачи в состояние Running) всегда выбирает для запуска задачу с наивысшим приоритетом, которая может запуститься. То, что высокоприоритетные задачи в настоящий момент не могут запуститься означает, что шедулер их пока не может выбрать и должен вместо этого выбрать одну из задач с более низким приоритетом. Таким образом, использование управляемых событиями задач означает, что задачи могут быть созданы с некоторыми разными приоритетами, причем высокоуровневые задачи не будут полностью отнимать процессорное время у низкоуровневых.

Blocked (заблокировано)

Состоянии заблокировано (Blocked state) является подсостоянием состояния Not Running и означает, что задача ожидает событие.

Задачи могут войти в Blocked state для ожидания событий двух разных типов:

  1. События времени - событие, которое возникает при истечении периода задержки или при достижении абсолютного времени. Например, задача может войти в Blocked state для ожидания прохождения 10 миллисекунд времени.
  2. События синхронизации - событие, поступившее от другой задачи или от прерывания. Например, задача может войти в Blocked state для ожидания поступления данных (появления их в очереди). События синхронизации покрывают широкий диапазон типов событий.

Можно устроить для задачи событие синхронизации с таймаутом, и эффективно обрабатывать оба типа событий (события времени и синхронизации). Например, задача может ожидать максимум 10 миллисекунд события появления данных в очереди. Задача покинет состояние Blocked state либо при поступлении данных на очереди, либо по истечении 10 миллисекунд (что означает таймаут поступления данных).

Состояние Suspended (приостановлено)

Suspended также является подсостоянием состояния Not Running. Задачи в состоянии suspended недоступны для шедулера. Есть только один способ входа в состояние Suspended - через вызов API функции vTaskSuspend(), и только один способ выхода из состояния Suspended - через вызов API функции vTaskResume() или (если вызов происходит из прерывания) xTaskResumeFromISR(). Большинство приложений никогда не используют состояние Suspended.

Состояние Ready (готово к запуску)

О задачах, которые находятся в состоянии Not Running, а также не в состояниях Blocked или Suspended, говорят, что они находятся в состоянии Ready. Они могут быть запущены и, таким образом, 'готовы к запуску' (Ready), но в настоящий момент не находятся в состоянии Running.

Формы распространения

Дистрибутив FreeRTOS может быть свободно скачан с сайта разработчика, бесплатно и без предоставления какой-либо информации (регистрации, заполнения каких-либо форм и т. п.). Документация в состав самого дистрибутива не входит, она доступна на сайте разработчика.

В состав дистрибутива входят подготовленные конфигурационные файлы и демонстрационные программы для каждой архитектуры, что позволяет очень быстро начать новую разработку. Для читаемости и лёгкости модификации код большей частью написан на Си, ассемблерные вставки используются в минимальном объёме в платформоспецифичных участках. Сайт разработчика также содержит подробное руководство по использованию и портированию FreeRTOS. В качестве кросс-компилятора предполагается использование GCC.[Источник 5]

Вариации

Проект «SafeRTOS»— доработанный, документированный, протестированный и прошедший сертификацию (в мае 2007) на соответствие стандарту безопасности IEC 61508 вариант FreeRTOS. Это коммерческий продукт, другой проприетарный коммерческий вариант системы, OpenRTOS отличается от свободной версии помимо лицензии и предоставляемых гарантий лишь некоторыми деталями.

Примечания

Источники

  1. FreeRTOS // Википедия [2017]. URL: https://ru.wikipedia.org/wiki/FreeRTOS (дата обращения: 27.05.2017).
  2. FreeRTOS: межпроцессное взаимодействие// habrahabr [2006-2017]. URL: https://habrahabr.ru/post/129180/ (дата обращения: 27.05.2017).
  3. FreeRTOS: мьютексы и критические секции// habrahabr [2006-2017]. URL: https://habrahabr.ru/post/129445/ (дата обращения: 27.05.2017).
  4. Введение: о чем говорится в части 1// microsin [2017]. URL: http://microsin.net/programming/ARM/freertos-part1.html (дата обращения: 27.05.2017).
  5. FreeRTOS// wikipedia [2017-2017]. URL: https://ru.wikipedia.org/wiki/FreeRTOS#.D0.A1.D0.B2.D0.BE.D0.B9.D1.81.D1.82.D0.B2.D0.B0 (дата обращения: 27.05.2017).