1 freeRTOS动态创建与静态创建
动态创建:从FreeRTOS 管理的内存堆中申请创建对象所需的内存,在对象删除后,
这块内存释放回FreeRTOS管理的内存堆中
静态创建:需用户提供各种内存空间,并且使用静态方式占用的内存空间一般固定下来了,即使任务、队列等被删除后,这些被占用的内存空间一般没有其他用途
2 FreeRTOS内存管理算法
常用算法 heap_4
3 4种算法详解
3.1 heap_1
/* 定义一个大数组作为 FreeRTOS 管理的内存堆 */
static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
3.2 heap_2
heap_2 内存管理算法使用最适应算法,并且支持释放内存,但不能将相邻的空闲内存块合并成一个大的空闲内存块。
3.3 heap_4
使用了首次适应算法,也支持内存的申请与释放,并且能够将空闲且相邻的内存进行合并,从而减少内存碎片的现象。
3.4 heap_5
1)heap_5 内存管理算法是在 heap_4 内存管理算法的基础上实现的,但是 heap_5 内存管理算法在 heap_4 内存管理算法的基础上实现了管理多个非连续内存区域的能力
2)heap_5 内存管理算法默认并没有定义内存堆 , 需要用户手动指定内存区域的信息,对其进行初始化。
typedef struct HeapRegion{uint8_t * pucStartAddress; /* 内存区域的起始地址 */size_t xSizeInBytes; /* 内存区域的大小,单位:字节 */} HeapRegion_t; Const HeapRegion_t xHeapRegions[] ={{ (uint8_t *)0x80000000, 0x10000 }, /* 内存区域 1 */{ (uint8_t *)0x90000000, 0xA0000 }, /* 内存区域 2 */{ NULL, 0 } /* 数组终止标志*/ };vPortDefineHeapRegions(xHeapRegions);
适用场景:在嵌入式系统中,那些内存的地址并不连续的场景。
4 FreeRTOS内存管理相关API函数
1)申请内存
void * pvPortMalloc( size_t xWantedSize );
形参:
xWantedSize:申请的内存大小,以字节为单位
返回值:
其他指针 成功
NULL 申请内存失败
2)释放内存
void vPortFree( void * pv );
形参:
pv: 指针指向一个要释放内存的内存块
3)获取当前空闲内存大小
size_t xPortGetFreeHeapSize( void )
返回值:
size_t 返回当前剩余的空闲内存大小
4 FreeRTOS内存管理实战
#include "freertos_demo.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"/******************************************************************************************************/
/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO 1 /* 任务优先级 */
#define START_STK_SIZE 128 /* 任务堆栈大小 */
TaskHandle_t StartTask_Handler; /* 任务句柄 */
void start_task(void *pvParameters); /* 任务函数 *//* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK1_PRIO 2 /* 任务优先级 */
#define TASK1_STK_SIZE 128 /* 任务堆栈大小 */
TaskHandle_t Task1Task_Handler; /* 任务句柄 */
void task1(void *pvParameters); /* 任务函数 *//******************************************************************************************************//*** @brief FreeRTOS例程入口函数* @param 无* @retval 无*/
void freertos_demo(void)
{xTaskCreate((TaskFunction_t )start_task, /* 任务函数 */(const char* )"start_task", /* 任务名称 */(uint16_t )START_STK_SIZE, /* 任务堆栈大小 */(void* )NULL, /* 传入给任务函数的参数 */(UBaseType_t )START_TASK_PRIO, /* 任务优先级 */(TaskHandle_t* )&StartTask_Handler); /* 任务句柄 */vTaskStartScheduler();
}/*** @brief start_task* @param pvParameters : 传入参数(未用到)* @retval 无*/
void start_task(void *pvParameters)
{taskENTER_CRITICAL(); /* 进入临界区 *//* 创建任务1 */xTaskCreate((TaskFunction_t )task1,(const char* )"task1",(uint16_t )TASK1_STK_SIZE,(void* )NULL,(UBaseType_t )TASK1_PRIO,(TaskHandle_t* )&Task1Task_Handler);vTaskDelete(StartTask_Handler); /* 删除开始任务 */taskEXIT_CRITICAL(); /* 退出临界区 */
}/*** @brief task1* @param pvParameters : 传入参数(未用到)* @retval 无*/
void task1(void *pvParameters)
{uint8_t key = 0,t = 0;uint8_t * buf =NULL;while (1){key = key_scan(0);//申请内存if(key == KEY0_PRES){buf = pvPortMalloc(30);if(buf != NULL){printf("内存申请成功\r\n");}else{printf("内存申请失败\r\n");}}//释放内存else if(key == KEY1_PRES){if(buf != NULL){vPortFree(buf);printf("内存释放成功\r\n");}}//获取空闲内存大小if(t++ >50){t=0;printf("剩余空闲内存大小:%d\r\n",xPortGetFreeHeapSize());}vTaskDelay(10);}
}