FreeRTOS学习--61讲 内存管理

内存申请:

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

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

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

你可能感兴趣的:(学习)