FreeRTOS——内存管理知识总结及实战

发布时间:2024年01月05日

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);
    }
}

文章来源:https://blog.csdn.net/m0_73502349/article/details/135413920
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。