=============================== 博客点滴积累,部分话语和知识点来源于网络,感谢网络资源的提供者======
heap1 只是一个简单的pvPortMalloc实现,并没有实现vPortFree函数,即不能回收再分配,heap1 比较简单,注释很完善很好理解,,需要注意的是创建task都是在heap上分配stack 和 tcb的,做笔记以备忘。
//定义字节对齐大小
#define portBYTE_ALIGNMENT8
/* A few bytes might be lost to byte aligning the heap start address. */
#define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT )
//根据字节对齐大小,设定对齐掩码
#if portBYTE_ALIGNMENT == 8
#define portBYTE_ALIGNMENT_MASK ( 0x0007U )
#endif
#if portBYTE_ALIGNMENT == 4
#define portBYTE_ALIGNMENT_MASK( 0x0003 )
#endif
#if portBYTE_ALIGNMENT == 2
#define portBYTE_ALIGNMENT_MASK( 0x0001 )
#endif
#if portBYTE_ALIGNMENT == 1
#define portBYTE_ALIGNMENT_MASK( 0x0000 )
#endif
/* Allocate the memory for the heap. */
/*configTOTAL_HEAP_SIZE 在freertosconfig.h 定义*/
static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];//heap 其实是一个大的数组
static size_t xNextFreeByte = ( size_t ) 0;
void *pvPortMalloc( size_t xWantedSize )
{
void *pvReturn = NULL;
static uint8_t *pucAlignedHeap = NULL;
/* 判断是否需要字节对齐. */
#if portBYTE_ALIGNMENT != 1
if( xWantedSize & portBYTE_ALIGNMENT_MASK )
{/* 调整使其字节对齐. */
xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
}
#endif
vTaskSuspendAll();//挂起所有的任务,禁止调度
{
if( pucAlignedHeap == NULL )//判断是否初始化过
{
/* 调整pucAlignedHeap 是其指向的地址是读取的,为什么是这个&ucHeap[ portBYTE_ALIGNMENT ],而不是&ucHeap[0],主要目的还是考虑地址被&后超出了heap的地址范围,比如&ucHeap[0]地址如果小于等于portBYTE_ALIGNMENT_MASK ,&后地址就为0了,出了heap的范围了,所以heapsize 就是configADJUSTED_HEAP_SIZE*/
pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ( portPOINTER_SIZE_TYPE ) ~portBYTE_ALIGNMENT_MASK ) );
}
/* 判断是否有足够的空间被分配*/
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();//唤醒task
/*configUSE_MALLOC_FAILED_HOOK 在freertos里定义,看名知意,malloc 分配失败的调试回调函数*/
#if( configUSE_MALLOC_FAILED_HOOK == 1 )
{
if( pvReturn == NULL )
{
extern void vApplicationMallocFailedHook( void );
vApplicationMallocFailedHook();
}
}
#endif
return pvReturn;
}
void vPortFree( void *pv )
{
/* Memory cannot be freed using this scheme. See heap_2.c, heap_3.c and
heap_4.c for alternative implementations, and the memory management pages of
http://www.FreeRTOS.org for more information. */
( void ) pv;
/* Force an assert as it is invalid to call this function. */
configASSERT( pv == NULL );
}
}