Original: http://blog.csdn.net/zhzht19861011/article/details/51606068
Memory management is important for both the application and the operating system. Now many of the program vulnerabilities and run crashes are related to memory allocation using errors. The FreeRTOS operating system implements the kernel and memory management separately, and the operating system kernel only prescribes the necessary memory management function prototypes, rather than how these memory management functions are implemented. This can be beneficial in terms of increasing the flexibility of the system: different applications can use different memory allocation implementations and choose a more advantageous memory management strategy for themselves. For example, for a secure embedded system, where dynamic memory allocation is not normally allowed, a very simple memory management strategy can be used, once the requested memory is not even allowed to be released. The simpler the system is, the easier it is to be safer to meet the requirements of the design. For example, some complex applications that require dynamic application and release of memory operations can also design a relatively complex memory management strategy that allows for dynamic allocation and dynamic release.
Several of the memory management function prototypes specified by the FreeRTOS kernel are:
void *pvportmalloc (size_t xsize): Memory request function void Vportfree (void *PV): Memory free function void vportinitialiseblocks (void): Initialize memory heap function size_t xportgetfreeheapsize (void): Gets the currently unallocated memory heap size size_t xportgetminimumeverfreeheapsize (void): Gets the unallocated memory heap history minimum value FreeRTOS provides 5 memory management implementations, simple and complex, and can be applied to most applications. They are located in the download package directory ... \freertos\source\portable\memmang, the file names are: heap_1.c, heap_2.c, heap_3.c, heap_4.c, heap_5.c, respectively. In the 8th chapter of the FreeRTOS series---freertos memory management, this article describes the features of these 5 memory management and their respective applications, and today we will analyze how they are implemented.
The memory management provided by FreeRTOS is allocated memory from the memory heap. By default, the FreeRTOS kernel creates tasks, queues, semaphores, event groups, and software timers by using memory management functions to allocate memory from the memory heap. The latest version of FreeRTOS (V9.0.0 and above) can use the static memory allocation method completely, that is, no memory heap is used.
For the three memory management strategies of heap_1.c, heap_2.c, and heap_4.c, the memory heap is actually a large array, defined as:
Static uint8_t ucheap[configtotal_heap_size];
Where macro configtotal_heap_size is used to define the size of the memory heap, this macro is set in FreeRTOSConfig.h.
For HEAP_3.C, this strategy simply wraps the malloc () and free () functions in the standard library, and the Wrapped malloc () and free () functions are thread-protected. Therefore, the memory heap needs to be set up by the compiler or the startup file.
HEAP_5.C is interesting, it allows programs to set up multiple non-contiguous memory heaps, such as a memory heap that requires quick access to set on-chip RAM, slightly slower access to the memory heap set in external RAM. The starting address and size of each memory heap is defined by the Application Designer.
1. heap_1.cThis is the simplest of 5 memory management strategies, which we call the first memory management policy, which is simple enough to request memory only. Yes, as you think, once the application is successful, the memory can no longer be released. This memory management strategy is useful for most embedded systems, especially those with high security requirements, because the simpler the logic is, the easier it is to be safe for the system software. In fact, most embedded systems do not need to dynamically delete tasks, semaphores, queues, etc., but are created once at the time of initialization, and are always used, never deleted. Therefore, this memory management strategy is simple, safe and reliable, and is widely used. I also have a passion for this memory management strategy.
We can think of the first memory management as cutting bread: the initialized memory is like a full baguette, and each time the memory is applied, the appropriate length of bread is cut from one end to the applicant until the bread is allocated.
This memory management policy uses two local static variables to track memory allocations, which are defined as:
[OBJC]View Plain copy print? static size_t Xnextfreebyte = (size_t) 0; static uint8_t *pucalignedheap = NULL; Where the variable Xnextfreebyte records the allocated memory size, which is used to locate the next free memory heap location. Because the memory heap is actually a large array, we just need to know the size of the allocated memory, and we can use it as an offset to find the starting address of the unallocated memory. The variable xnextfreebyte is initialized to 0, and then each request for memory succeeds increases the number of bytes requested for memory.
The variable pucalignedheap points to the starting position of the memory heap after alignment. Why to align. This is because most hardware accesses memory-aligned data faster. To improve performance, the FreeRTOS will be aligned, with different hardware architecture alignment operations, and a 8-byte alignment for the CORTEX-M3 architecture.
Let's look at the API functions provided externally by the first memory management policy.
1.1 Memory Request: Pvportmalloc ()The function source code is:
[OBJC] View plain copy print? Voidvoid *pvportmalloc ( size_t xWantedSize ) { voidvoid * pvreturn = null; static uint8_t *pucalignedheap = null; /* Ensure that the number of bytes requested is a multiple of the number of aligned bytes */ #if ( portBYTE_ALIGNMENT != 1 ) { if ( xwantedsize & portbyte_alignment_ mask ) { xWantedSize += ( portbyte_alignment - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); } }  &NBsp; #endif vtasksuspendall (); { if ( pucalignedheap == null ) { /* first use to ensure correct alignment of the memory heap start position */ pucalignedheap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) & ucheap[ portbyte_alignment ] ) & ( ~ ( ( portpointer_size_type ) portBYTE_ALIGNMENT_MASK ) ) ; } /* boundary Check, Variable xnextfreebyte is a local static variable with an initial value of 0 */&Nbsp;