FreeRTOS学习--61讲 内存管理

发布时间:2023年12月29日

内存申请:

? ? ? ? 动态申请:任务申请后得到的内存地址,在任务删除后,会自动释放回收到内存堆中

? ? ? ? 静态申请:即使得到这块内存的任务被删除后,这块内存依旧无法使用

Freertos的内存管理方法

????????heap_1:最简单,只允许申请内存,不允许释放内存。
????????heap_2:允许申请和释放内存,但不能合并相邻的空闲内存块。
????????heap_3:简单封装 C 库的函数 malloc()和函数 free(),以确保线程安全。
????????heap_4:允许申请和释放内存,并且能够合并相邻的空闲内存块,减少内存碎片的产生。
????????heap_5:能够管理多个非连续内存区域的 heap_4。

heap_2的特点:

? ? ? ? 最适应算法:a.先把空闲内存块从小到大排序

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? b.把大小适合的内存块再分割出需要的大小

? ? ? ? 缺点:内存块越分越小,且无法合并,最后无内存可用

? ? ? ? 适用场景:频繁的创建删除任务,且所创建任务堆栈都相同

heap_4的特点:

? ? ? ? 首次适应算法:a.先把空闲内存块从大到小排序

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?b.选择最大的内存块切出需要的大小

? ? ? ? 缺点:依旧会产生不连续地址的内存块

? ? ? ? 适用场景:适用于在程序中多次创建和删除任务、队列、信号量等的应用

内存管理相关API?????????freertos内存大小为10K

pvPortMalloc(size_t xWantedSize) ? ????????????????申请内存
参数:内存的大小(以字节为单位)????????????????返回值:指针 指向分配的内存,失败 NULL
void vPortFree(void* pv) ??? ??? ????????????????????????????释放内存
参数: 指向内存块的指针
size_t ?xPortGetFreeHeapSize(void) ????????????????获取当前休闲内存的大小
????????????????????????????????????????????????????????????????返回值: 剩余空闲内存大小(字节单位)

不能重复释放内存,会造成内存泄露,申请一次内存,释放一次

配置动态内存管理的条件:

? ? ? ?在FreeRTOSConfig.h 文件中
????????/* 1: 支持动态申请内存, 默认: 1 */
????????#define configSUPPORT_DYNAMIC_ALLOCATION 1
????????/* FreeRTOS堆中可用的 RAM 总量, 单位: Byte, 无默认需定义 */
????????#define configTOTAL_HEAP_SIZE ((size_t)(10 * 1024))

内存管理实验

????????

//freertos_demo.c

#include "freertos_demo.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
#include "./SYSTEM/delay/delay.h"
#include "./MALLOC/malloc.h"
/*FreeRTOS******************************************************************************/
#include "FreeRTOS.h"
#include "task.h"

/***************************************************************************************/
/*FreeRTOS配置*/

/* START_TASK 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define START_TASK_PRIO      1
#define START_TASK_STACK_SIZE 128
TaskHandle_t  start_task_handler;
void start_task(void * pvParameters);

/* TASK1 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
  */
  
#define TASK1_PRIO      2
#define TASK1_STACK_SIZE 128
TaskHandle_t  task1_handler;
 void task1(void* pv);
 
/***************************************************************************************/


/**
 * @brief       FreeRTOS例程入口函数
 * @param       无
 * @retval      无
 */
void freertos_demo(void)
{    
    xTaskCreate((TaskFunction_t    )    start_task,         //创建开始任务
                (char*             )    "start_task", 
                (unsigned portSHORT)    START_TASK_STACK_SIZE, 
                (void *            )    NULL, 
                (portBASE_TYPE     )    START_TASK_PRIO, 
                (TaskHandle_t*     )    &start_task_handler );
    vTaskStartScheduler();
}

void start_task(void* pvPara)
{
    taskENTER_CRITICAL();         //进入临界区
    
    xTaskCreate((TaskFunction_t    )    task1,              //创建任务一
                (char*             )    "task1", 
                (unsigned portSHORT)    TASK1_STACK_SIZE, 
                (void *            )    NULL, 
                (portBASE_TYPE     )    TASK1_PRIO, 
                (TaskHandle_t*     )    &task1_handler );
                

                
    vTaskDelete(NULL);              //删除start_task任务
    taskEXIT_CRITICAL();            //退出临界区
}


//任务一 申请内存 释放内存,显示空闲内存大小
void task1(void* pv)
{
    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 if(key == KEY1_PRES)
        {
            if(buf != NULL)
            {
                printf("释放内存!!!\r\n");
                vPortFree(buf);             //释放内存
            }
        }
        if(++t > 50)
        {
            t = 0;
            printf("剩余的空闲内存大小为:%d\r\n",xPortGetFreeHeapSize());//获取剩余空间大小
        }
        vTaskDelay(10);
    }
}

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