Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

ОС реального времени FreeRTOS

Глава 3 из книги "Архитектура приложений с открытым исходным кодом", том 2.
Оригинал: FreeRTOS
Автор: Christopher Svec
Перевод: Н.Ромоданов

3.2. Обзор архитектуры

Система FreeRTOS является относительно небольшим приложением. Минимальный вариант ядра системы FreeRTOS состоит всего лишь из трех файлов исходного кода (.c) и горстка файлов заголовков, общий размер которых составляет чуть менее 9000 строк кода, включая комментарии и пустые строки. Размер типичного образа системы в исполняемом коде меньше 10 КБ.

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

  • Задачи: Почти половина кода ядра FreeRTOS связана с с центральной проблемой, решаемой во многих операционных системах: управление задачами. Задачей является определяемая пользователем функция на языке C с заданным приоритетом. В tasks.c и task.h делается вся тяжелая работа по созданию, планированию и обслуживанию задач.
  • Коммуникации: Задачи хороши, но задачи, которые могут общаться друг с другом, еще лучше! Это подводит нас ко второй части работ, выполняемых FreeRTOS: коммуникации. Около 40% кода ядра системы FreeRTOS связано с коммуникациями. Обработка коммуникаций в системе FreeRTOS осуществляется в файлах queue.c и queue.h. Задачи и прерывания используют очереди для передачи данных друг другу, а для того, чтобы сигнализировать об использовании критических ресурсов, применяются семафоры (semaphore) и и мютексы (mutexe).
  • Подключение к оборудованию: Около 9000 строк кода, которые составляют базу системы FreeRTOS, являются аппаратно-независимыми; один и тот же код выполняется независимо от того, работает ли система на скромной процессоре 8051 или на новейшем сияющим ядре ARM. Около 6% код ядра системы FreeRTOS представляют собой прослойку между аппаратно-независимым ядром системы FreeRTOS и аппаратно-зависимым кодом. Мы обсудим аппаратно-зависимый кода в следующем разделе.

Об аппаратном обеспечении

Аппаратно-независимый слой системы FreeRTOS находится поверх аппаратно-зависимого слоя. В этом аппаратно-зависимом слое известно, как взаимодействовать с архитектурой, построенной на любом чипе, который вы выберете. На рис.3.1 показаны слои системы FreeRTOS.

Рис.3.1: Слои программного обеспечения системы FreeRTOS

Система FreeRTOS поставляемый со всем аппаратно-независимым, а также с аппаратно-зависимым кодом, который вы должны получить для того, чтобы настроить и запустить систему. Поддерживается большое количество компиляторов (CodeWarrior, GCC, IAR и т.д.), а также большое количество архитектур процессоров (ARM7, ARM Cortex-M3, различные PIC, Silicon Labs 8051, x86 и т.д.). Список поддерживаемых архитектур и компиляторов смотрите на сайте системы FreeRTOS.

Дизайн системы FreeRTOS позволяет ее легко настраивать в широких пределах. Система FreeRTOS может собрана как для одного процессора, для выполнения только основных функций и поддержки только нескольких задач, либо она может быть собрана для работы на многоядерном железе с TCP/IP, файловой системой и USB.

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

#define configMAX_PRIORITIES      ( ( unsigned portBASE_TYPE ) 5 )
#define configCPU_CLOCK_HZ        ( 12000000UL )
#define configTICK_RATE_HZ        ( ( portTickType ) 1000 )
#define configMINIMAL_STACK_SIZE  ( ( unsigned short ) 100 )
#define configTOTAL_HEAP_SIZE     ( ( size_t ) ( 4 * 1024 ) )

Аппаратно-зависимую код для каждого инструментального набора компиляции и для каждой архитектуры процессора располагается в отдельных файлах. Например, если вы работаете с компилятором IAR на чипе ARM Cortex-M3, то аппаратно-зависимый код будет находиться в каталоге FreeRTOS/Source/portable/IAR/ARM_CM3/. В файле portmacro.h объявляются все аппаратно-зависимые функции, а в файлах port.c и portasm.s находится весь фактически используемый аппаратно-зависимый код. Во время компиляции аппаратно-независимые заголовки #include файла portable.h заменяются файлом portmacro.h. Система FreeRTOS вызывает аппаратно-зависимые функции с помощью функций #define, объявленных в файле portmacro.h.

Давайте посмотрим на пример того, как система FreeRTOS вызывает аппаратно-зависимую функцию. Для того, чтобы войти в критическую секцию кода для предотвращения вытеснения, часто требуется аппаратно-независимый файл tasks.c. В различных архитектурах вход в критическую секцию происходит по-разному, и, желательно, чтобы аппаратно-независимый файл tasks.c не касался деталей, связанных с аппаратной зависимостью. Поэтому tasks.c вызывает глобальный макрос portENTER_CRITICAL(), радуясь тому, что не требуется знать как и что на самом деле работает. Предположим, что мы используем компилятор IAR на чипе ARM Cortex-M3, система FreeRTOS будет собираться с заголовками FreeRTOS/Source/portable/IAR/ARM_CM3/portmacro.h, в который макрос portENTER_CRITICAL() определяется следующим образом:

#define portENTER_CRITICAL()   vPortEnterCritical()

На самом деле vPortEnterCritical() определяется в файле FreeRTOS/Source/portable/IAR/ARM_CM3/port.c. Файл port.c является аппаратно-зависимым и содержит код, который понятен компилятору IAR и чипу Cortex-M3. vPortEnterCritical() выполняет переход в критическую секцию, используя знания, касающиеся конкретного оборудования, и возвращает управление аппаратно-независимому файлу tasks.c.

В файле portmacro.h также определяются базовые типы данных для используемой архитектуры. Ниже приведен пример типов данных для базовых целочисленных переменных, указателей и данные тактовой частоты системы для компилятора IAR на чипе ARM Cortex-M3:

#define portBASE_TYPE  long              // Тип базовой целочисленной переменной
#define portSTACK_TYPE unsigned long     // Указатели на позиции в памяти
typedef unsigned portLONG portTickType;  // Тип тактовой частоты системы

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

Как мы уже видели, система FreeRTOS реализует аппаратно-зависимую функциональность с помощью макросов #define препроцессора языка C. В системе FreeRTOS определения #define также используются большей части аппаратно-независимого кода. Для невстраиваемых приложений такое частое использование определений #define является кардинальным недостатком, но во многих небольших встроенных системах накладные расходы на вызов функции не дают преимуществ в сравнении с использованием «реальных» функций.


Продолжение статьи: Планирование задач: Краткий обзор