====== TNKernel : Блоки памяти фиксированного размера ======
===== Введение =====
Стандартные функции ''malloc/free'' как правило не являются безопасными с точки зрения многозадачности, поэтому необходимо либо отказаться от их применения, либо рассматривать кучу (heap) как разделяемый ресурс (использовать мютекс), либо реализовать менеджер памяти своими силами под конкретную задачу.
//Пул блоков памяти фиксированного размера// - объект RTOS, предназначенный для динамического выделения памяти в многозадачной среде - может частично решить эту проблему. Пул представляет собой набор блоков памяти фиксированного размера (как правило, кратного машинному слову) и управляющую структуру, которая определяет занятые и свободные блоки.
Задача может получить блок памяти. Если в пуле нет свободных блоков, то задача переводится в состояние ожидания до тех пор, пока один из блоков не освободится или пока не истечет таймаут сервиса запроса. После использования блока задача может освободить его.
~~UP~~
===== Структура управления пулом блоков памяти =====
Каждый пул ассоциируется со структурой управления:
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;
В состав структуры пула входят следующие элементы:
{| class = "fpl"
|-
| ''wait_queue''
| Очередь задач, ожидающих освобождение блока
|-
| ''block_size''
| Размер блока памяти в байтах
|-
| ''num_blocks''
| Количество блоков в пуле
|-
| ''start_addr''
| Указатель на область памяти, выделенную для пула
|-
| ''free_list''
| Указатель на список свободных блоков
|-
| ''fblkcnt''
| Количество свободных блоков
|-
| ''id_fmp''
| Поле идентификации объекта как пула блоков памяти
|}
Структура пула доступна только при определении ''TN_DEBUG''. Тем не менее, прямой доступ к элементам структуры пула блоков памяти крайне не рекомендуется, так как это является вмешательством в работу планировщика и других сервисов RTOS.
~~UP~~
===== Сервисы управления пулами блоков памяти =====
TNKernel имеет следующий набор функций (сервисов) для управления пулами:
^ Сервис ^ Описание ^ Свойства ^
| **Создание и удаление пула** |||
| \ \ [[tnkernel:ref:mpool:tn_fmem_create|tn_fmem_create()]] | Создание пула | {{tnkernel:ref:attr_call_task_and_int.png|Разрешен вызов в контексте задачи и в прерывании}} |
| \ \ [[tnkernel:ref:mpool:tn_fmem_delete|tn_fmem_delete()]] | Удаление пула | {{tnkernel:ref:attr_call_task.png|Разрешен вызов только в контексте задачи}} {{tnkernel:ref:attr_call_ct_sw.png|Может привести к переключению контекста}} |
| **Получение блока памяти** |||
| \ \ [[tnkernel:ref:mpool:tn_fmem_get|tn_fmem_get()]] | Получение блока памяти | {{tnkernel:ref:attr_call_task.png|Разрешен вызов только в контексте задачи}} {{tnkernel:ref:attr_call_ct_sw.png|Может привести к переключению контекста}} {{tnkernel:ref:attr_call_to.png|Сервис использует таймаут}} |
| \ \ [[tnkernel:ref:mpool:tn_fmem_get_polling|tn_fmem_get_polling()]] | Получение блока памяти без блокировки задачи | {{tnkernel:ref:attr_call_task.png|Разрешен вызов только в контексте задачи}} {{tnkernel:ref:attr_call_ct_sw.png|Может привести к переключению контекста}} |
| \ \ [[tnkernel:ref:mpool:tn_fmem_get_ipolling|tn_fmem_get_ipolling()]] | Получение блока памяти в прерывании | {{tnkernel:ref:attr_call_int.png|Разрешен вызов только в прерывании}} {{tnkernel:ref:attr_call_ct_sw.png|Может привести к переключению контекста}} |
| **Освобождение блока памяти** |||
| \ \ [[tnkernel:ref:mpool:tn_fmem_release|tn_fmem_release()]] | Освобождение блока памяти | {{tnkernel:ref:attr_call_task.png|Разрешен вызов только в контексте задачи}} {{tnkernel:ref:attr_call_ct_sw.png|Может привести к переключению контекста}} |
| \ \ [[tnkernel:ref:mpool:tn_fmem_irelease|tn_fmem_irelease()]] | Освобождение блока памяти в прерывании | {{tnkernel:ref:attr_call_int.png|Разрешен вызов только в прерывании}} {{tnkernel:ref:attr_call_ct_sw.png|Может привести к переключению контекста}} |
~~UP~~