freertos 内存分配 源码分析
2014-06-16 00:00
316 查看
摘要: freertos 内存分配 源码分析
xBlockLink
堆栈初始化
static xBlockLink xStart, xEnd;
static union xRTOS_HEAP
{
#if portBYTE_ALIGNMENT == 8 //这里为 8
volatile portDOUBLE dDummy;
#else
volatile unsigned long ulDummy;
#endif
unsigned char ucHeap[ configTOTAL_HEAP_SIZE ];
} xHeap;
内存
static const unsigned short heapSTRUCT_SIZE = ( sizeof( xBlockLink ) + portBYTE_ALIGNMENT - ( sizeof( xBlockLink ) % portBYTE_ALIGNMENT ) );
static const unsigned short heapSTRUCT_SIZE = ( sizeof( xBlockLink ) + portBYTE_ALIGNMENT - ( sizeof( xBlockLink ) % portBYTE_ALIGNMENT ) ); //分配的块空间对齐
分配内存对齐原理:如size大小15 原理就为 15+8-(15%8)=16 为2个8字节
xBlockLink
typedef struct A_BLOCK_LINK { struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ size_t xBlockSize; /*<< The size of the free block. */ } xBlockLink;
堆栈初始化
static xBlockLink xStart, xEnd;
static union xRTOS_HEAP
{
#if portBYTE_ALIGNMENT == 8 //这里为 8
volatile portDOUBLE dDummy;
#else
volatile unsigned long ulDummy;
#endif
unsigned char ucHeap[ configTOTAL_HEAP_SIZE ];
} xHeap;
#define prvHeapInit() \ { \ xBlockLink *pxFirstFreeBlock; \ /* xStart is used to hold a pointer to the first item in the list of free */ \ /* blocks. The void cast is used to prevent compiler warnings. */ \ xStart.pxNextFreeBlock = ( void * ) xHeap.ucHeap; \ xStart.xBlockSize = ( size_t ) 0; \ \ /* xEnd is used to mark the end of the list of free blocks. */ \ xEnd.xBlockSize = configTOTAL_HEAP_SIZE; //17*1024 17字节 \ xEnd.pxNextFreeBlock = NULL; \ /* To start with there is a single free block that is sized to take up the \ entire heap space. */ \ pxFirstFreeBlock = ( void * ) xHeap.ucHeap; \ pxFirstFreeBlock->xBlockSize = configTOTAL_HEAP_SIZE; \ pxFirstFreeBlock->pxNextFreeBlock = &xEnd; \ }
内存
static const unsigned short heapSTRUCT_SIZE = ( sizeof( xBlockLink ) + portBYTE_ALIGNMENT - ( sizeof( xBlockLink ) % portBYTE_ALIGNMENT ) );
void *pvPortMalloc( size_t xWantedSize ) { xBlockLink *pxBlock, *pxPreviousBlock, *pxNewBlockLink; static portBASE_TYPE xHeapHasBeenInitialised = pdFALSE; void *pvReturn = NULL; vTaskSuspendAll(); { //第一次 if( xHeapHasBeenInitialised == pdFALSE ) { prvHeapInit(); xHeapHasBeenInitialised = pdTRUE; } if( xWantedSize > 0 ) { xWantedSize += heapSTRUCT_SIZE; if( xWantedSize & portBYTE_ALIGNMENT_MASK ) //需要的空间对齐 { xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); } } if( ( xWantedSize > 0 ) && ( xWantedSize < configTOTAL_HEAP_SIZE ) ) { pxPreviousBlock = &xStart; //指向起始地址 pxBlock = xStart.pxNextFreeBlock; // while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock ) ) { pxPreviousBlock = pxBlock; //找到合适大小 pxBlock = pxBlock->pxNextFreeBlock; // } if( pxBlock != &xEnd ) { pvReturn = ( void * ) ( ( ( unsigned char * ) pxPreviousBlock->pxNextFreeBlock ) + heapSTRUCT_SIZE ); //获得分配的需要的空间地址 /* 从空闲的内存链表中移除 */ pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; /*如果比需要的大,可以分为两块*/ if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) { pxNewBlockLink = ( void * ) ( ( ( unsigned char * ) pxBlock ) + xWantedSize ); pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; //新划分出来的空间块 pxBlock->xBlockSize = xWantedSize; /* 把新分配的空间块 添加到 空闲块链表中 */ prvInsertBlockIntoFreeList( ( pxNewBlockLink ) ); } xFreeBytesRemaining -= pxBlock->xBlockSize; //空闲块大小减去刚刚用掉的大小 } } } xTaskResumeAll(); #if( configUSE_MALLOC_FAILED_HOOK == 1 ) { if( pvReturn == NULL ) { extern void vApplicationMallocFailedHook( void ); vApplicationMallocFailedHook(); } } #endif return pvReturn; //返回需求的内存空间地址 }
static const unsigned short heapSTRUCT_SIZE = ( sizeof( xBlockLink ) + portBYTE_ALIGNMENT - ( sizeof( xBlockLink ) % portBYTE_ALIGNMENT ) ); //分配的块空间对齐
分配内存对齐原理:如size大小15 原理就为 15+8-(15%8)=16 为2个8字节
相关文章推荐
- nginx 源码学习笔记(七)——内存分配相关源码分析
- Libevent源码分析-----内存分配
- 【golang 源码分析】内存分配与管理
- Java对象内存分配原理及源码分析
- 内存、分配-OMXCodec源码分析---part2-by小雨
- jdk源码分析(四)——垃圾收集器与内存分配策略
- Libevent源码分析-----内存分配
- Netty学习之旅----源码分析内存分配与释放原理
- 【redis源码分析】内存分配---zmalloc
- Redis源码分析-内存分配
- Box2D源码分析:栈内存分配B2StackAllocator
- CloudSim源码分析之主机资源分配(内存篇)
- 深入分析Linux内核源码——6.3 内存的分配和回收
- 源码分析:Java对象的内存分配
- nginx 源码学习笔记(七)——内存分配相关源码分析
- MySQL源码分析(2):Mysql中的内存分配相关
- Libevent源码分析-----内存分配
- 源码分析:Java对象的内存分配
- 源码分析:Java对象的内存分配
- python源码分析----内存分配(2)