FreeRTOS代码剖析之3:内存管理Heap_3.c

来源:互联网 发布:java的spring框架 编辑:程序博客网 时间:2024/06/16 11:29


http://xilinx.eetrend.com/blog/8181


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个下次继续剖析。之后应该能进入内核了吧?

原创粉丝点击