嵌入式面试——FreeRTOS篇(九) 内存管理

本篇为:FreeRTOS 内存管理篇

一、FreeRTOS内存管理简介

1、FreeRTOS内存管理介绍

答:

        在使用 FreeRTOS 创建任务、队列、信号量等对象的时,一般都提供了两种方法:

  • 动态方法创建:自动地从 FreeRTOS 管理的内存堆中申请创建对象所需的内存,并且在对象删除后,可将这块内存释放回FreeRTOS管理的内存堆。由FreeRTOS自动实现了malloc和free。
  • 静态方法创建:需用户提供各种内存空间,并且使用静态方式占用的内存空间一般固定下来了,即使任务、队列等被删除后,这些被占用的内存空间一般没有其他用途。

总结:

        动态方式管理内存相比与静态方式,更加灵活。

        除了 FreeRTOS 提供的动态内存管理方法,标准的C库也提供了函数 malloc()和函数 free()来实现动态地申请和释放内存。

        那么问题就来了!

2、为什么不用标准的C库自带的内存管理算法

答:

        因为标准 C 库的动态内存管理方法有如下几个缺点:

  • 占用大量的代码空间 不适合用在资源紧缺的嵌入式系统中。
  • 没有线程安全的相关机制。
  • 运行有不确定性,每次调用这些函数时花费的时间可能都不相同。
  • 内存碎片化。

        因此,FreeRTOS 提供了多种动态内存管理的算法,可针对不同的嵌入式系统!

二、FreeRTOS内存管理算法

1、FreeRTOS内存管理算法种类

答:

        FreeRTOS提供了5种动态内存管理算法,分别为: heap1、heap2、heap_3、heap4、heap5 。其实是5个.C 文件,这5个文件就是这5中算法的实现。

如图所示:

        在我们FreeRTOS例程中,使用的均为heap_4内存管理算法。

2、heap_1内存管理算法

答:

heap_1的特点:

        heap1只实现了pvPortMalloc,没有实现vPortFree;也就是说,它只能申请内存,无法释放内存!

        如果你的工程,创建好的任务、队列、信号量等都不需要被删除,那么可以使用heap1内存管理算法。

        heap1的实现最为简单,管理的内存堆是一个数组,在申请内存的时候, heap1 内存管理算法只是简单地从数组中分出合适大小的内存,内存堆数组的定义如下所示 :

/* 定义一个大数组作为 FreeRTOS 管理的内存堆 */

static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];

heap_1内存管理算法的分配过程如下图所示:

注意

        heap_1内存管理算法,只能申请无法释放!

3、heap_2内存管理算法

答:

heap_2的特点:

  • 相比于 heap1 内存管理算法, heap2 内存管理算法使用最适应算法,并且支持释放内存
  • heap2 内存管理算法并不能将相邻的空闲内存块合并成一个大的空闲内存块;因此 heap2 内存管理算法不可避免地会产生内存碎片;

最适应算法:

  • 假设heap有3块空闲内存(按内存块大小由小到大排序):5字节、25字节、50字节。
  • 现在新创建一个任务需要申请20字节的内存。
  • 第一步:找出最小的、能满足pvPortMalloc的内存:25字节。
  • 第二步:把它划分为20字节、5字节;返回这20字节的地址,剩下的5字节仍然是空闲状态,留给后续的pvPortMalloc使用。

heap_2内存管理算法的分配过程:

        内存碎片是由于多次申请和释放内存,但释放的内存无法与相邻的空闲内存合并而产生的。

适用场景:

        频繁的创建和删除任务,且所创建的任务堆栈都相同,这类场景下Heap_2没有碎片化的问题。

Heap_3用的是C库实现的,所以跳过。

4、heap_4内存管理算法

答:

heap_4的特点:

        heap_4 内存管理算法使用了首次适应算法,也支持内存的申请与释放,并且能够将空闲且相邻的内存进行合并,从而减少内存碎片的现象。

首次适应算法:

  • 假设heap有3块空闲内存(按内存块地址由低到高排序):5字节、50字节、25字节。
  • 现在新创建一个任务需要申请20字节的内存。
  • 第一步:找出第一个能满足pvPortMalloc的内存:50字节。
  • 第二步:把它划分为20字节、30字节;返回这20字节的地址,剩下30字节仍然是空闲状态,留给后续的pvPortMalloc使用。

heap_4内存管理算法的分配过程:

        heap_4内存管理算法会把相邻的空闲内存合并为一个更大的空闲内存,这有助于减少内存的碎片问题。

适用于这种场景:

        频繁地分配、释放不同大小的内存。

5、heap_5内存管理算法

答:

heap_5的特点:

        heap5 内存管理算法是在 heap4 内存管理算法的基础上实现的,但是 heap5 内存管理算法在 heap4 内存管理算法的基础上实现了管理多个非连续内存区域的能力。

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

 

适用场景:

        在嵌入式系统中,那些内存的地址并不连续的场景。

三、FreeRTOS内存管理相关API函数

1、FreeRTOS内存管理相关函数

答:

void * pvPortMalloc( size_t xWantedSize );

void vPortFree( void * pv );

size_t xPortGetFreeHeapSize( void );

嵌入式开发中,FreeRTOS是一个常用的实时操作系统(RTOS)。它为嵌入式系统提供了多任务管理、任务调度、中断处理以及内存管理等功能。在面试中,针对FreeRTOS可能会有以下几个方面的问题: 1. 介绍FreeRTOS的特点和优势。 FreeRTOS具有以下几个特点和优势: - 轻量级:代码占用空间小,运行时内存消耗低。 - 可移植性:支持多种处理器架构和开发环境。 - 多任务管理:支持任务的创建、删除、挂起、恢复等操作。 - 任务调度:使用优先级和时间片轮转算法,实现任务调度。 - 中断处理:提供了中断处理机制,使得中断与任务可以协同工作。 - 内存管理:支持堆和栈的内存分配和释放,避免内存泄漏和碎片化。 - 丰富的组件:提供了定时器、信号量、消息队列等组件,方便开发。 2. 如何创建一个FreeRTOS任务? 在FreeRTOS中,可以使用函数xTaskCreate创建一个任务。该函数需要指定任务函数和任务的优先级等参数。例如: ``` void vTaskFunction(void *pvParameters) { // 任务函数的代码 } int main() { // 初始化系统和硬件 // ... // 创建任务 xTaskCreate(vTaskFunction, "TaskName", stackSize, NULL, priority, NULL); // 启动调度器 vTaskStartScheduler(); // 不会执行到这里 return 0; } ``` 3. 如何实现任务间的通信和同步? FreeRTOS提供了多种机制用于任务间的通信和同步,例如: - 信号量(Semaphore):用于任务间的同步和资源的保护。 - 互斥量(Mutex):用于任务间对共享资源的互斥访问。 - 队列(Queue):用于任务间的消息传递和数据共享。 - 事件标志组(Event Group):用于任务之间的事件通知和等待。 4. 如何处理中断和任务之间的关系? 在FreeRTOS中,中断处理和任务可以协同工作。可以使用函数xTaskResumeFromISR来从中断中恢复被挂起的任务。另外,还可以使用中断服务例程(ISR)向队列发送消息,然后由任务来处理这些消息。 总结来说,面试中关于FreeRTOS的问题可能会涉及其特点和优势、任务的创建、任务间的通信和同步、以及中断和任务之间的关系。熟悉这些方面可以更好地回答相关问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式小杨

恭喜你啊恭喜你,恭喜老板发大财

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值