FreeRTOS: плюсы и минусы статического и динамического выделения памяти Печать
Добавил(а) microsin   

Версии FreeRTOS до V9.0.0 выделяли память для своих объектов (задачи, очереди, мьютексы, семафоры, ...) из специальной кучи FreeRTOS (какие бывают варианты куч и как они настраиваются, см. [3]). FreeRTOS V9.0.0 и более свежие версии дают разработчику приложения возможность предоставлять память для объектов статически. Таким образом, следующие объекты могут быть созданы без какого-либо динамического выделения памяти:

• Задачи (Tasks).
• Программные таймеры (Software Timers).
• Очереди (Queues).
• Группы событий (Event Groups).
• Двоичные семафоры (Binary Semaphores).
• Семафоры со счетчиком (Counting Semaphores).
• Рекурсивные семафоры (Recursive Semaphores).
• Мьютексы (Mutexes).

Как лучше выделять память под объекты - статически или динамически - решает для себя программист, в зависимости от требований разрабатываемого приложения. У обоих методов есть достоинства и недостатки, и оба метода могут использоваться в пределах одного и того же приложения FreeRTOS.

Простой пример Win32 находится в директории FreeRTOS/Source/WIN32-MSVC-Static-Allocation-Only распространяемого пакета исходного кода FreeRTOS. В нем демонстрируется, как может быть создано приложение FreeRTOS без подключения какой-либо реализации кучи FreeRTOS [3].

[Создание объекта с динамическим выделением RAM]

Динамическое создание объектов RTOS лучше в том плане, что упрощает программирование, и потенциально может минимизировать максимальное потребление оперативной памяти (RAM) приложением:

• При создании объекта меньше требуется указывать параметров.
• Выделение памяти происходит автоматически, внутри API-функций FreeRTOS.
• Разработчику приложения не нужно специально концентрироваться на выделении памяти при создании объектов.

RAM, которая была использована для объекта FreeRTOS, может быть повторно использована, если этот объект был удален, что потенциально снижает потребности приложения в оперативной памяти.

Предоставлены API-функции FreeRTOS, возвращающие информацию об использовании кучи, что также позволяет оптимизировать её размер.

Может быть выбрана схема выделения памяти, которая больше всего походит специфике приложения. Это может быть выбрана схема heap_1.c для упрощения и для детерминизма времени выполнения, что часто требуется для критически важных для безопасности приложений, heap_4.c для защиты от фрагментации кучи, heap_5.c для кучи, память которой размещается в нескольких не смежных регионах памяти [3]. Или может быть применена схема выделения с пользовательской логикой, которую запрограммировал сам разработчик приложения.

Когда опция configSUPPORT_DYNAMIC_ALLOCATION установлена в 1 или оставлена не определенной, доступны следующие API-функции, создающие объекты FreeRTOS в динамически выделяемой оперативной памяти RAM:

xTaskCreate()
xQueueCreate()
xTimerCreate()
xEventGroupCreate()
xSemaphoreCreateBinary()
xSemaphoreCreateCounting()
xSemaphoreCreateMutex()
xSemaphoreCreateRecursiveMutex()

[Создание объекта со статическим выделением RAM]

Создание объектов FreeRTOS в статически выделенном RAM дает разработчику больше контроля и обладает следующими преимуществами:

• Объекты FreeRTOS могут быть размещены в специфических областях памяти. Например, некоторые области RAM (такие как внутренняя память MCU) работают быстрее других областей (таких как внешняя память SDRAM), что дает возможность особо критичные ко времени доступа объекты размещать в самой быстрой памяти.
• Максимальное потребление памяти RAM приложением может быть определено уже во время сборки приложения (link time), а не во время его работы (run time).
• Разработчику не нужно волноваться о корректной работе выделения памяти и о проблемам с отказами из-за неудачных попыток выделения блока.

Статическое выделение памяти в FreeRTOS может использоваться в тех приложениях, которым просто не нужно динамическое выделение памяти. Хотя FreeRTOS включает схемы выделения, которые могут преодолеть большинство возражений против статического выделения памяти (в частности, схема heap_1.c обладает такими же параметрами, как и статическое выделение).

Когда определена в 1 опция configSUPPORT_STATIC_ALLOCATION, доступны следующие API-функции, позволяющие создавать объекты FreeRTOS в памяти, предоставленной разработчиком. Чтобы предоставить память таким способом, разработчику просто нужно декларировать переменную объекта подходящего типа, и затем передать адрес этой переменной в API-функцию FreeRTOS.

xTaskCreateStatic()
xQueueCreateStatic()
xTimerCreateStatic()
xEventGroupCreateStatic()
xSemaphoreCreateBinaryStatic()
xSemaphoreCreateCountingStatic()
xSemaphoreCreateMutexStatic()
xSemaphoreCreateRecursiveMutexStatic()

Предоставляется стандартный демонстрационный пример StaticAllocation.c, показывающий, как использовать эти функции.

[Ссылки]

1. Static Vs Dynamic Memory Allocation site:freertos.org.
2. Statically Allocated FreeRTOS Reference Project site:freertos.org.
3. FreeRTOS: управление памятью.