内存申请:
? ? ? ? 动态申请:任务申请后得到的内存地址,在任务删除后,会自动释放回收到内存堆中
? ? ? ? 静态申请:即使得到这块内存的任务被删除后,这块内存依旧无法使用
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);
}
}