Memory Management
Glossary:
heap segmentation
:RAM
is not a complete memory space to meet the needs of application memory, but the overall situation of the remaining space is greater than demand.这就表现了分配算法的重要性。
Stack & Heap
stack
(Stack), sometimes called frame
(frame). A subroutine (subroutine, in fact, a function) information is stored in a frame. This information includes the return address of the function and the incoming parameters. When the function is called again, the information will be put on the stack, and when the function returns, the information will be popped out of the stack and restored to the register.
Every time a variable is defined in the function, it will be stored on the stack. When the function returns, the entire stack space is released. The advantage of the stack is that the entire stack space allocated can be used by the function, and there is no need to dynamically allocate or release space.
to sum up:
- the stack grows and shrinks as functions push and pop local variables
- there is no need to manage the memory yourself, variables are allocated and freed automatically
- the stack has size limits
- stack variables only exist while the function that created them, is running
Heap
It is a dynamically allocated space, managed by the operating system* (no longer separate function management like the stack)*. The space in the heap can be allocated, released, and resized during program execution. These actions malloc
and free
implementation.
Stack:
- very fast access
- don’t have to explicitly de-allocate variables
- space is managed efficiently by CPU, memory will not become fragmented
- local variables only
- limit on stack size (OS-dependent)
- variables cannot be resized
Heap:
- variables can be accessed globally
- no limit on memory size
- (relatively) slower access
- no guaranteed efficient use of space, memory may become fragmented over time as blocks of memory are allocated, then freed
- you must manage memory (you’re in charge of allocating and freeing variables)
- variables can be resized using
realloc()
Dynamic Memory Allocation
FreeRTOS
To realize the memory allocation protable layer
, you can customize the memory allocation algorithm to achieve different scene requirements. When the need for memory, call pvPortMalloc()
with vPortFree()
. Corresponding to both the C malloc()
and free()
.
FreeRTOS achieve five distribution, respectively heap_1.c
, heap_2.c
, heap_3.c
, heap_4.c
, heap_5.c
.
Heap_1
The target scenario is system initialization, and the allocated memory will continue until the end of the program. Heap1
Only realized the pvPortMalloc()
function is not implemented vPortFree()
functions. (No release was considered at all) . Heap_1
Heap size is determined by FreeRTOSConfig.h
the configTOTAL_HEAP_SIZE
decision. The icons are as follows:
The large rectangular box is a pile, which configTOTAL_HEAP_SIZE
determines the size. Each task made TCB
and Stack
(stack) components. Creating a task allocates a space for it in the heap.
Here a task should be a process (function), so the stack is used.
Heap_2
heap_2
The heap_1
same, a large space is cut into smaller blocks used by the program. the difference lies in:
heap_2
Allow space to be freedheap_2
The allocation algorithm is implemented instead of direct allocation.
heap_2
Will not allocate the remaining space after integrate, to fragmentation
be more sensitive. The distribution process is as follows:
Heap_3
Direct use of C malloc
and free
. At this configTOTAL_HEAP_SIZE
failure, decided to no longer heap size. heap_3
The advantage is that thread-safe
and scheduler suspension
.
Heap_4
And heap_1
, heap_2
the same principle: the monolithic stack is divided into small blocks used for scheduling. heap_4
The remaining small blocks will be integrated to form a large memory block. Used to handle situations where memory request sizes are different. Icon:
Heap_5
The Heap_4
basis can define a plurality of RAM
block sizes. Therefore, the call pvPortMalloc()
before allocates memory, you need to initialize - vPortDefineHeapRegions() ()
. Example:
// declaration of vPortDefineHeapRegions
void vPortDefineHeapRegions(const HeapRegion_t* const pxHeapRegions);
// declaration of HeapRegion_t
typedef struct HeapRegion
{
// start address of a block of memory that will be part of the heap
uint_8* pucStartAddress;
// size of the block
size_t xSizeInBytes;
}
/* Define the start address and size of the three RAM regions. */
#define RAM1_SIZE ( 65 * 1024 )
static uint_8 ucHeap[RAM1_SIZE];
#define RAM2_START_ADDRESS ( ( uint8_t * ) 0x00020000 )
#define RAM2_SIZE ( 32 * 1024 )
#define RAM3_START_ADDRESS ( ( uint8_t * ) 0x00030000 )
#define RAM3_SIZE ( 32 * 1024 )
/* Create an array of HeapRegion_t definitions, with an index for each of the three RAM regions,
and terminating the array with a NULL address. The HeapRegion_t structures must appear in start address
order,with the structure that contains the lowest start address appearing first. */
const HeapRegion_t xHeapRegions[] =
{
{ ucHeap, RAM1_SIZE },
{ RAM2_START_ADDRESS, RAM2_SIZE },
{ RAM3_START_ADDRESS, RAM3_SIZE },
{ NULL, 0 } /* Marks the end of the array. */
};
int main( void )
{
/* Initialize heap_5. */
vPortDefineHeapRegions( xHeapRegions );
/* Add application code here. */
}
Here, using an array to declare a space in RAM1 is to hand over the final absolute address to the linker. Because there are other variables in RAM1, which will occupy a part of the space, the first address of RAM1 cannot be used directly.
For example STM32 from the
0x2000 0000
beginning is an internal RAM,0x6000 0000
initially outside the RAM . You can only declare the internal RAM size and space in thelink script
( link file ). Thenheap_5
declared external RAM space allocated for use by the operating system.
to sum up
heap_1
: Only allocate, not release, suitable for always-existing situationsheap_2
: It can be released, but the remaining memory blocks will not be integrated. It is suitable for applications where the memory size is the same or similarheap_3
: C is achievedmalloc
andfree
functionsheap_4
: You can release and integrate the remaining memory blocks, suitable for applications with different memory sizesheap_5
: Custom RAM block size and location for allocation.
Use function summary
- pvPortMalloc()
- vPortFree()
- vPortDefineHeapRegions()
- xPortGetFreeHeapSize()
- xPortGetMinimumEverFreeHeapSize()
- void vApplicationMallocFailedHook( void )
This is the callback function when memory allocation fails, and needs to be configUSE_MALLOC_FAILED_HOOK
set to 1.
Reference article
- Mastering the FreeRTOS ™Real Time Kernel