Freertos内存管理

在Freertos创建任务、信号量、队列等对象的时候,一般提供两种从创建方法,一是动态创建,二是静态创建,相比于静态创建,动态创建是Freertos从自己管理管理得内存中进行分配,在删除任务得时候,又可以释放之前创建得内存堆,比静态创建任务灵活许多。

除了Freertos中管理的内存算法,也可以使用C库提供的malloc()和free()来实现动态创建管理内存,但存在一下缺点:
1.会占用大量的代码空间

2.具有不确定性,表现为每次执行的时间不同

3.没有线程安全得相关机制

Freertos中提供了5中内存管理算法,分别是heap_1.c、heap_2.c、heap_3.c、heap_4.c、heap_5.c,这5种分别具有一下特点:

heap_1:只允许申请内存,不允许释放内存(适用于 个别嵌入式系统,一旦创建好就不会删除的任务)

heap_2:允许申请释放内存,但不能合并相邻空闲的内存块(会产生大量的内存碎片)

heap_3:简单封装了C库的malloc()、free()函数,确保线程安全

heap_4:允许申请和释放内存,并且可以合并相邻的内存块,减少内存碎片的产生(常用的内存管理算法)

heap_5:相当于可以管理多个非连续区域的heap_4(感觉像是heap_4的升级版);

相关的内存管理函数:

pvPortMalloc(pv):pv:所要申请的内存的大小,并返回内存的首地址

vPortFree(pv):pv:需要删除内存的首地址

xPortGetFreeHeapSize():获取申请内存的大小。

简单的实验:

/**
 * @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)
{
    while(1)
    {
		uint8_t key = 0;
		uint8_t *buf = NULL;
		size_t free_size = 0;
		while (1)
		{
			key = key_scan(0);
			
			switch (key)
			{
				case KEY0_PRES:
				{
					buf = pvPortMalloc(30);    /* 申请内存 */
					break;
				}
				case KEY1_PRES:
				{
					if (NULL != buf)
					{
						vPortFree(buf);
						buf = NULL;
					}
					break;
				}
				default:
					break;
			}
			printf("总内存大小%d\r\n" ,configTOTAL_HEAP_SIZE);
			free_size = xPortGetFreeHeapSize();
			printf("剩余内存大小%d\r\n" , free_size);
			
		}
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值