FreeRTOS Heap简易分析
- 架构:Cortex-M3
- 版本:FreeRTOS V9.0.0
- 前言:队列、任务、信号量等都是需要内存来保存的,FreeRTOS提供了五种分配内存的方式。
目录
1.Heap1.c
直接找到heap1.c来分析
可以看到,代码并不多,至少能说明heap1的分配内存方式应该是很简单的。
从代码中可以看出,heap1只有分配,没有释放。
那么我们具体看分配函数pvPortMalloc
:
void *pvPortMalloc( size_t xWantedSize )
{
void *pvReturn = NULL;
static uint8_t *pucAlignedHeap = NULL;
/* Ensure that blocks are always aligned to the required number of bytes. */
#if( portBYTE_ALIGNMENT != 1 )
{
if( xWantedSize & portBYTE_ALIGNMENT_MASK )
{
/* Byte alignment required. */
xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
}
}
#endif
vTaskSuspendAll();
{
if( pucAlignedHeap == NULL )
{
/* Ensure the heap starts on a correctly aligned boundary. */
pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) );
}
/* Check there is enough room left for the allocation. */
if( ( ( xNextFreeByte + xWantedSize ) < configADJUSTED_HEAP_SIZE ) &&
( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) )/* Check for overflow. */
{
/* Return the next free byte then increment the index past this
block. */
pvReturn = pucAlignedHeap + xNextFreeByte;
xNextFreeByte += xWantedSize;
}
traceMALLOC( pvReturn, xWantedSize );
}
( void ) xTaskResumeAll();
#if( configUSE_MALLOC_FAILED_HOOK == 1 )
{
if( pvReturn == NULL )
{
extern void vApplicationMallocFailedHook( void );
vApplicationMallocFailedHook();
}
}
#endif
return pvReturn;
}
首先是字节对齐,根据不同硬件,字节对齐的长度不同。Cortex-M3是以8字节对齐的时候访问内存是更快的。heap1处理字节对齐是 &0x07
,然后加上portBYTE_ALIGNMENT - xWantedSize & portBYTE_ALIGNMENT_MASK
这个值,就可以做到字节对齐了。
如果是第一次分配的话,会先检查ucHeap
是否处于字节对齐的位置,计算出对齐的位置后赋值给pucAlignedHeap
,那么以后分配内存的时候都是以pucAlignedHeap
的位置来开始分配。
分配内存时,会检查当前内存够不够分、有没有出现溢出的问题。xNextFreeByte
是个全局变量,表示当前这个堆已经分配的大小,每次都会加上分配的内存大小,通过这个值,至少能得出当前用了多少RAM和还剩多少WRAM可用
heap1初始化图解:
2.heap2.c
heap2比heap复杂一下,重点在于分配和释放时,是以一种机制来操作的。
2.1申请内存
首先看prvHeapInit
static void prvHeapInit( void )
{
BlockLink_t *pxFirstFreeBlock;
uint8_t *pucAlignedHeap;
/* Ensure the heap starts on a correctly aligned boundary. */
pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) &