单片机
返回首页

FreeRTOS代码剖析之3:内存管理Heap

2024-05-07 来源:elecfans

FreeRTOS8.0.1的第三个模型Heap_3,可以说是最容易理解的一个内存堆管理模型。因为在这个模型里,FreeRTOS直接将标准C库中的malloc()和free()进行加工打包。(Implementation of pvPortMalloc() and vPortFree() that relies on the compilers own malloc() and free() implementations.)因此,FreeRTOSConfig.h中的configTOTAL_HEAP_SIZE在这个模型中就失效了。FreeRTOS直接管理编译器编译时分配的堆。例如,在STM32F103中,FreeRTOS管理的堆就定义在启动文件startup_stm32f10x_xd.s中。


不过,就算是直接引用了标准C库中的malloc()和free()也是不行的。原因是库中的这两个接口在FreeRTOS中并不是线程安全的。因此,FreeRTOS将这两个接口进行重新打包。首先看看pvPortMalloc()是怎么将malloc()重新打包的。
void *pvPortMalloc( size_t xWantedSize )
{
void *pvReturn;

vTaskSuspendAll();
{
pvReturn = malloc( xWantedSize );
traceMALLOC( pvReturn, xWantedSize );
}
( void ) xTaskResumeAll();

#if( configUSE_MALLOC_FAILED_HOOK == 1 )
{
if( pvReturn == NULL )
{
extern void vApplicationMallocFailedHook( void );
vApplicationMallocFailedHook();
}
}
#endif

return pvReturn;
}

这一段就是pvPortMalloc()的所有代码,很短,也很容易理解。首先,和Heap_1、Heap_2一样,用vTaskSuspendAll()挂起所有的任务,以确保分配内存的过程是线程安全的。接下来才使用malloc()进行内存分配。然后就是调用调试信息宏traceMALLOC()并调用xTaskResumeAll()恢复被挂起的任务。这样基本的分配内存流程就结束了。如果在FreeRTOS.h中设置了勾子函数宏,则在调用勾子函数vApplicationMallocFailedHook()之后再向用户返回分配内存的首地址。

void vPortFree( void *pv )
{
if( pv )
{
vTaskSuspendAll();
{
free( pv );
traceFREE( pv, 0 );
}
( void ) xTaskResumeAll();
}
}

上面这一段代码是vPortFree()对free()的重新包装。过程也是很简单。首先是检查指针的有效性,然后挂起所有任务,调用free()接口将内存回收,接着调用调试信息宏traceFREE(),最后恢复所有挂起进程。这样整个回收过程就结束了。


总结:一开始的时候看到原有的注释说明,就不想为这个模型剖析下去了。不过后来想想,要成大事必从小事做起,就算是简单也不能放弃,所以还是把这一部分的代码剖析了。以后不能再有这种懒惰的想法了。FreeRTOS中4个内存堆管理模型已经剖析完3个了,还有1个下次继续剖析。之后应该能进入内核了吧?


进入单片机查看更多内容>>
相关视频
  • 【TI MSPM0 应用实战】智能小车+工业角度编码器+血氧仪+烟雾探测器!硬核参考设计详解!

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

  • 直播回放: Microchip Timberwolf™ 音频处理器在线研讨会

  • 基于灵动MM32W0系列MCU的指夹血氧仪控制及OTA升级应用方案分享

精选电路图
  • 1瓦线性调频增强器

  • 1瓦四级调频发射机

  • 500W MOS场效应管电源逆变器,12V转110V/220V

  • 红外开关

  • LM317过压保护

  • 0-30V/20A 大功率稳压电源(采用LM338)

    相关电子头条文章