====== 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~~