FreeRTOS——堆内存管理

FreeRTOS 基础系列文章

 基本对象
  FreeRTOS——任务
  FreeRTOS——队列
  FreeRTOS——信号量
  FreeRTOS——互斥量
  FreeRTOS——任务通知
  FreeRTOS——流和消息缓冲区
  FreeRTOS——软件定时器
  FreeRTOS——事件组

 内存管理
  FreeRTOS——静态与动态内存分配
  FreeRTOS——堆内存管理
  FreeRTOS——栈溢出保护

 代码组织
  FreeRTOS——源代码组织
  FreeRTOS——创建新的项目
  FreeRTOS——配置文件


内存管理

每次创建任务、队列、互斥量、软件计时器、信号量或事件组时,RTOS 内核都需要 RAM。RAM 可以在 RTOS API 对象创建函数中从 RTOS 堆自动动态分配,也可以由应用程序设计者提供。

如果 RTOS 对象是动态创建的,那么有时可以使用标准 C 库 malloc()free() 函数来实现此目的,但是······

  1. 它们并不总是在嵌入式系统上可用,
  2. 它们占用了宝贵的代码空间,
  3. 它们不是线程安全的,并且
  4. 它们不是确定性的(执行函数所花费的时间会因调用而异)

······所以通常需要另一种内存分配实现。

一个嵌入式/实时系统可能与另一个系统具有非常不同的 RAM 和时序要求 —— 因此单个 RAM 分配算法将只适用于应用程序的一个子集(还可以有其他分配算法)。

为了解决这个问题,FreeRTOS 将内存分配 API 保留在其可移植层中。可移植层位于实现核心 RTOS 功能的源文件之外,允许提供适用于正在开发的实时系统的特定于应用程序的实现。当 RTOS 内核需要 RAM 时,它不会调用 malloc(),而是调用 pvPortMalloc()。当 RAM 被释放时,RTOS 内核不会调用 free(),而是调用 vPortFree()。

FreeRTOS 提供了多种堆管理方案,其复杂性和功能各不相同。也可以提供您自己的堆实现,甚至可以同时使用两个堆实现。同时使用两个堆实现允许将任务堆栈和其他 RTOS 对象放置在快速的内部 RAM 中,并将应用程序数据放置在较慢的外部 RAM 中。


RTOS 源代码下载中包含的内存分配实现

FreeRTOS 下载中包括五个示例的内存分配实现,每个都在以下小节中进行了描述。这些小节还包括关于提供的每个实现最适合在哪些情况下使用的信息。

每个提供的实现都包含在一个单独的源文

### 关于FreeRTOS内存管理的面试问题及解答 #### 1. FreeRTOS 中如何分配动态内存? 在 FreeRTOS 中,提供了两种标准 API 函数用于动态内存分配:`pvPortMalloc()` 和 `vPortFree()`. 使用这两个函数可以像使用 C 标准库中的 `malloc()` 和 `free()` 一样方便地申请和释放内存[^3]. ```c void* pvPortMalloc(size_t xWantedSize); void vPortFree(void *pv); ``` 需要注意的是,在某些情况下,为了提高性能或满足特定需求,开发者可以选择实现自定义版本的 `pvPortMalloc()` 和 `vPortFree()`. #### 2. FreeRTOS 支持几种不同的内存分配方案? FreeRTOS 默认提供四种不同类型的内存分配策略: - **heap_1.c**: 实现简单的首次适配算法。 - **heap_2.c**: 提供最小空间碎片化处理。 - **heap_3.c**: 调用底层操作系统的 malloc/free. - **heap_4.c**: 基于最佳匹配原则优化了 heap_1, 并加入了边界标记法防止溢出。 每种方式都有其特点,适用于不同类型的应用场景。选择合适的内存管理模块对于减少系统开销至关重要[^4]. #### 3. 如何避免 FreeRTOS 应用程序中的内存泄漏? 为了避免内存泄漏的发生,应该遵循以下几点建议: - 总是在不再需要时调用 `vPortFree()` 来释放之前通过 `pvPortMalloc()` 分配出来的内存区域; - 尽可能重用已经存在的对象而不是频繁创建销毁它们; - 定期检查应用程序是否存在未被正确回收的对象实例; 此外还可以考虑启用配置选项 `configUSE_MALLOC_FAILED_HOOK`, 当发生连续多次失败请求时触发钩子函数以便调试分析原因所在. #### 4. FreeRTOS 是否允许静态内存分配? 除了传统的动态内存分配外,FreeRTOS 还支持完全不依赖于任何形式的动态内存分配——即所谓的“纯静态”模式。在这种模式下,所有必要的数据结构都预先声明并初始化好,从而消除了运行期间可能出现的风险因素如内存耗尽等问题。要开启此功能需设置宏定义 `configSUPPORT_STATIC_ALLOCATION` 为 1,并相应调整其他相关参数. ```c #define configSUPPORT_STATIC_ALLOCATION 1 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值