ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

为什么 FreeRTOS 需要自己的堆内存管理(heap_1 ~ heap_5)

为什么 FreeRTOS 需要自己的堆内存管理(heap_1 ~ heap_5) 1. 引言在 FreeRTOS 中每个内核对象任务、队列、信号量、事件组等在创建时都需要分配内存。比如任务控制块TCB和每个任务单独的任务栈都需要从内存中申请空间。这就引出一个问题为什么 FreeRTOS 不直接使用 C 标准库的malloc和free而要自己实现一套堆内存管理方案也就是常说的 heap_1 ~ heap_52. 从单片机的内存布局说起以 STM32F103 这类单片机为例它的内存RAM通常被划分为几个区域data 段存放已初始化的全局变量和静态变量。bss 段存放未初始化或初始化为 0 的全局变量和静态变量。stack栈用于函数调用时的局部变量、返回地址等由编译器自动管理。heap堆用于动态内存分配也就是malloc/free操作的区域。在裸机程序中堆的使用相对简单但在 RTOS 环境下多个任务并发运行堆的管理就变得复杂起来。3. malloc 和 free 的不可重入问题在 C 语言中我们通常使用malloc和free来动态分配和释放内存。但标准库的这两个函数具有不可重入性。所谓不可重入是指一个函数不能被多次调用尤其是在中断或任务切换的上下文中而不会出错。具体来说malloc/free内部会维护一个全局的空闲内存链表。如果在任务 A 正在执行malloc的过程中任务 B 被调度进来也调用malloc就可能出现对同一块内存链表的同时访问导致链表损坏、内存泄漏甚至系统崩溃。在 FreeRTOS 中任务之间会频繁切换如果直接在任务里调用malloc/free显然很容易出错。4. FreeRTOS 的解决方案自己的堆内存管理为了解决上述问题FreeRTOS 实现了自己的一套堆内存管理方案也就是常说的heap_1 ~ heap_5。它们各有不同的特点和适用场景heap_1最简单只支持分配、不支持释放适合永不删除任务的场景。heap_2支持分配和释放但不会合并相邻的空闲内存块容易产生碎片。heap_3直接封装标准库的malloc/free但通过挂起调度器来保证线程安全。heap_4支持分配和释放并且会合并相邻空闲块是目前最常用的方案。heap_5在 heap_4 的基础上支持在多个不连续的内存区域上管理堆。5. 小结FreeRTOS 之所以需要自己实现堆内存管理核心原因就是标准库的malloc/free不可重入在多任务环境下容易出错。通过自己实现堆管理FreeRTOS 可以在保证线程安全的同时提供更可控、更高效的内存分配策略。下期我会详细讲解这五种堆内存管理方案的区别和优势敬请期待。
返回列表