Стандартные функции malloc/free
как правило не являются безопасными с точки зрения многозадачности, поэтому необходимо либо отказаться от их применения, либо рассматривать кучу (heap) как разделяемый ресурс (использовать мютекс), либо реализовать менеджер памяти своими силами под конкретную задачу.
Пул блоков памяти фиксированного размера - объект RTOS, предназначенный для динамического выделения памяти в многозадачной среде - может частично решить эту проблему. Пул представляет собой набор блоков памяти фиксированного размера (как правило, кратного машинному слову) и управляющую структуру, которая определяет занятые и свободные блоки.
Задача может получить блок памяти. Если в пуле нет свободных блоков, то задача переводится в состояние ожидания до тех пор, пока один из блоков не освободится или пока не истечет таймаут сервиса запроса. После использования блока задача может освободить его.
Каждый пул ассоциируется со структурой управления:
typedef struct _TN_FMP_S { CDLL_QUEUE_S wait_queue; TN_UWORD block_size; TN_UWORD num_blocks; void * start_addr; void * free_list; TN_UWORD fblkcnt; TN_OBJ_ID id_fmp; } TN_FMP_S;
В состав структуры пула входят следующие элементы:
wait_queue |
Очередь задач, ожидающих освобождение блока |
block_size |
Размер блока памяти в байтах |
num_blocks |
Количество блоков в пуле |
start_addr |
Указатель на область памяти, выделенную для пула |
free_list |
Указатель на список свободных блоков |
fblkcnt |
Количество свободных блоков |
id_fmp |
Поле идентификации объекта как пула блоков памяти |
TN_DEBUG
. Тем не менее, прямой доступ к элементам структуры пула блоков памяти крайне не рекомендуется, так как это является вмешательством в работу планировщика и других сервисов RTOS.
TNKernel имеет следующий набор функций (сервисов) для управления пулами:
Сервис | Описание | Свойства |
---|---|---|
Создание и удаление пула | ||
tn_fmem_create() | Создание пула | |
tn_fmem_delete() | Удаление пула | |
Получение блока памяти | ||
tn_fmem_get() | Получение блока памяти | |
tn_fmem_get_polling() | Получение блока памяти без блокировки задачи | |
tn_fmem_get_ipolling() | Получение блока памяти в прерывании | |
Освобождение блока памяти | ||
tn_fmem_release() | Освобождение блока памяти | |
tn_fmem_irelease() | Освобождение блока памяти в прерывании |