from : https://www.freertos.org/a00111.html
FreeRTOS keeps the memory allocation API in its portable layer. The portable layer is outside of the source files that implement the core RTOS functionality, allowing an application specific implementation appropriate for the real time system being developed to be provided. When the RTOS kernel requires RAM, instead of calling malloc(), it instead calls pvPortMalloc(). When RAM is being freed, instead of calling free(), the RTOS kernel calls vPortFree().
freertos 把 分配内存和释放内存 的接口留在了 portable layer。
两个接口 pvPortMalloc vPortFree
The FreeRTOS download includes five sample memory allocation implementations, each of which are described in the following subsections. The subsections also include information on when each of the provided implementations might be the most appropriate to select.
Each provided implementation is contained in a separate source file (heap_1.c, heap_2.c, heap_3.c, heap_4.c and heap_5.c respectively) which are located in the Source/Portable/MemMang directory of the main RTOS source code download. Other implementations can be added as needed. Exactly one of these source files should be included in a project at a time [the heap defined by these portable layer functions will be used by the RTOS kernel even if the application that is using the RTOS opts to use its own heap implementation].
下载的freertos 的源码自带 5 个内存管理器的实现。(heap_1.c, heap_2.c, heap_3.c, heap_4.c and heap_5.c)
一个项目中只能启用 5 个中的1 个。
Following below:
非常简单的实现,没有内存释放。
包含内存释放,但是内存释放时,不会合并空闲空间。
对标准库的malloc 的包裹
内存释放时会对相邻的空闲空间进行合并。包括 绝对地址位置的 选项。
和4相同,增加了 扩展内存到其他非相邻区域的能力。
Notes:
heap 4 是heap2的升级,heap2是heap1的升级。heap 1 的已经很少使用了。heap4是最好的选择。
进一步的 5中heap的优缺点,如下原文:
heap_1 is less useful since FreeRTOS added support for static allocation.
heap_1 is the simplest implementation of all. It does not permit memory to be freed once it has been allocated. Despite this, heap_1.c is appropriate for a large number of embedded applications. This is because many small and deeply embedded applications create all the tasks, queues, semaphores, etc. required when the system boots, and then use all of these objects for the lifetime of program (until the application is switched off again, or is rebooted). Nothing ever gets deleted.
The implementation simply subdivides a single array into smaller blocks as RAM is requested. The total size of the array (the total size of the heap) is set by configTOTAL_HEAP_SIZE - which is defined in FreeRTOSConfig.h. The configAPPLICATION_ALLOCATED_HEAP FreeRTOSConfig.h configuration constant is provided to allow the heap to be placed at a specific address in memory.
The xPortGetFreeHeapSize() API function returns the total amount of heap space that remains unallocated, allowing the configTOTAL_HEAP_SIZE setting to be optimised.
The heap_1 implementation:
heap_2 is now considered legacy as heap_4 is preferred.
heap_2 uses a best fit algorithm and, unlike scheme 1, allows previously allocated blocks to be freed. It does not combine adjacent free blocks into a single large block. See heap_4.c for an implementation that does coalescence free blocks.
The total amount of available heap space is set by configTOTAL_HEAP_SIZE - which is defined in FreeRTOSConfig.h. The configAPPLICATION_ALLOCATED_HEAP FreeRTOSConfig.h configuration constant is provided to allow the heap to be placed at a specific address in memory.
The xPortGetFreeHeapSize() API function returns the total amount of heap space that remains unallocated, (allowing the configTOTAL_HEAP_SIZE setting to be optimised), but does not provided information on how the unallocated memory is fragmented into smaller blocks.
This implementation:
heap_2.c is suitable for many small real time systems that have to dynamically create objects. See heap_4 for a similar implementation that combines free memory blocks into single larger blocks.
This implements a simple wrapper for the standard C library malloc() and free() functions that will, in most cases, be supplied with your chosen compiler. The wrapper simply makes the malloc() and free() functions thread safe.
This implementation:
Note that the configTOTAL_HEAP_SIZE setting in FreeRTOSConfig.h has no effect when heap_3 is used.
This scheme uses a first fit algorithm and, unlike scheme 2, it does combine adjacent free memory blocks into a single large block (it does include a coalescence algorithm).
The total amount of available heap space is set by configTOTAL_HEAP_SIZE - which is defined in FreeRTOSConfig.h. The configAPPLICATION_ALLOCATED_HEAP FreeRTOSConfig.h configuration constant is provided to allow the heap to be placed at a specific address in memory.
The xPortGetFreeHeapSize() API function returns the total amount of heap space that remains unallocated when the function is called, and the xPortGetMinimumEverFreeHeapSize() API function returns lowest amount of free heap space that has existed system the FreeRTOS application booted. Neither function provides information on how the unallocated memory is fragmented into smaller blocks.
The vPortGetHeapStats() API function provides additional information. It populates the members of a heap_t structure, as shown below.
/* Prototype of the vPortGetHeapStats() function. */ void vPortGetHeapStats( HeapStats_t *xHeapStats ); /* Definition of the Heap_stats_t structure. */ typedef struct xHeapStats { size_t xAvailableHeapSpaceInBytes; /* The total heap size currently available - this is the sum of all the free blocks, not the largest block that can be allocated. */ size_t xSizeOfLargestFreeBlockInBytes; /* The maximum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */ size_t xSizeOfSmallestFreeBlockInBytes; /* The minimum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */ size_t xNumberOfFreeBlocks; /* The number of free memory blocks within the heap at the time vPortGetHeapStats() is called. */ size_t xMinimumEverFreeBytesRemaining; /* The minimum amount of total free memory (sum of all free blocks) there has been in the heap since the system booted. */ size_t xNumberOfSuccessfulAllocations; /* The number of calls to pvPortMalloc() that have returned a valid memory block. */ size_t xNumberOfSuccessfulFrees; /* The number of calls to vPortFree() that has successfully freed a block of memory. */ } HeapStats_t;
heap_4:
heap_4.c is particularly useful for applications that want to use the portable layer memory allocation schemes directly in the application code (rather than just indirectly by calling API functions that themselves call pvPortMalloc() and vPortFree()).
This scheme uses the same first fit and memory coalescence algorithms as heap_4, and allows the heap to span multiple non adjacent (non-contiguous) memory regions.
Heap_5 is initialised by calling vPortDefineHeapRegions(), and cannot be used until after vPortDefineHeapRegions() has executed. Creating an RTOS object (task, queue, semaphore, etc.) will implicitly call pvPortMalloc() so it is essential that, when using heap_5, vPortDefineHeapRegions() is called before the creation of any such object.
vPortDefineHeapRegions() takes a single parameter. The parameter is an array of HeapRegion_t structures. HeapRegion_t is defined in portable.h as
typedef struct HeapRegion { /* Start address of a block of memory that will be part of the heap.*/ uint8_t *pucStartAddress; /* Size of the block of memory. */ size_t xSizeInBytes; } HeapRegion_t;
The HeapRegion_t type definition
The array is terminated using a NULL zero sized region definition, and the memory regions defined in the array must appear in address order, from low address to high address. The following source code snippets provide an example. The MSVC Win32 simulator demo also uses heap_5 so can be used as a reference.
/* Allocate two blocks of RAM for use by the heap. The first is a block of 0x10000 bytes starting from address 0x80000000, and the second a block of 0xa0000 bytes starting from address 0x90000000. The block starting at 0x80000000 has the lower start address so appears in the array fist. */ const HeapRegion_t xHeapRegions[] = { { ( uint8_t * ) 0x80000000UL, 0x10000 }, { ( uint8_t * ) 0x90000000UL, 0xa0000 }, { NULL, 0 } /* Terminates the array. */ }; /* Pass the array into vPortDefineHeapRegions(). */ vPortDefineHeapRegions( xHeapRegions );
Initialising heap_5 after defining the memory blocks to be used by the heap
The xPortGetFreeHeapSize() API function returns the total amount of heap space that remains unallocated when the function is called, and the xPortGetMinimumEverFreeHeapSize() API function returns lowest amount of free heap space that has existed system the FreeRTOS application booted. Neither function provides information on how the unallocated memory is fragmented into smaller blocks.
The vPortGetHeapStats() API function provides additional information on the heap status.