heap_1.c详解--------FreeRTOS内存管理

来源:互联网 发布:java与xml 编辑:程序博客网 时间:2024/06/03 20:07



heap_1源码分析


#include <stdlib.h>

/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
all the API functions to use the MPU wrappers.  That should only be done when
task.h is included from an application file. */
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE

#include "FreeRTOS.h"
#include "task.h"

#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE

#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 )
    #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0
#endif

/* A few bytes might be lost to byte aligning the heap start address. */
#define configADJUSTED_HEAP_SIZE    ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT )
//字节对齐后的内存大小
/* Allocate the memory for the heap. */
/* Allocate the memory for the heap. */
#if( configAPPLICATION_ALLOCATED_HEAP == 1 )
    /* The application writer has already defined the array used for the RTOS
    heap - probably so it can be placed in a special segment or address. */
    extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
#else
    static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];   //内存总大小
#endif /* configAPPLICATION_ALLOCATED_HEAP */

static size_t xNextFreeByte = ( size_t ) 0;

/*-----------------------------------------------------------*/

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 )             //设置为8字节对齐
    {
        if( xWantedSize & portBYTE_ALIGNMENT_MASK )    //判断xWantedSize是不是8字节对齐也就是是不是8的倍数   
        {
            /* Byte alignment required. */
            xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );            //做8字节对齐处理
        }
    }
    #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 ) ) );
         //确保内存堆的可用起始地址也是8字节对齐的  内存堆ucHeap的起始地址是由编译器分配的,不一定是8字节对齐的,多以要计算出一个8字节对齐的地址的可用起始地址pucAlignedHeap做字节对齐  地址是从pucAlignedHeap开始使用的
        
        }
        

        /* Check there is enough room left for the allocation. */
        if( ( ( xNextFreeByte + xWantedSize ) < configADJUSTED_HEAP_SIZE ) &&
            ( ( xNextFreeByte + xWantedSize ) > xNextFreeByte )    )/* Check for overflow. */
        //检查一下可用内存是否分配,分配以后是否产生越界(超出内存堆范围)xNextFreeByte是一个全局变量,用来保存pucALignedHeap到内存堆剩余内存首地址之间的偏移值
        {
        
            /* Return the next free byte then increment the index past this
            block. */
            pvReturn = pucAlignedHeap + xNextFreeByte;  //可用内存的首地址
            xNextFreeByte += xWantedSize;       
        }                //申请内存,即从内存对ucHeap中割出一块内存
        
        traceMALLOC( pvReturn, xWantedSize );        
    }
    ( void ) xTaskResumeAll();

    #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 );
}
/*-----------------------------------------------------------*/

void vPortInitialiseBlocks( void )    //获取剩余内存大小
{
    /* Only required when static memory is not cleared. */
    xNextFreeByte = ( size_t ) 0;
}
/*-----------------------------------------------------------*/

size_t xPortGetFreeHeapSize( void )
{
    return ( configADJUSTED_HEAP_SIZE - xNextFreeByte );
}