FreeRTOS —— Memory Management

Memory Management

Glossary: heap segmentation: RAMis 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

HeapIt 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 mallocand freeimplementation.

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

FreeRTOSTo 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. Heap1Only realized the pvPortMalloc()function is not implemented vPortFree()functions. (No release was considered at all) . Heap_1Heap size is determined by FreeRTOSConfig.hthe configTOTAL_HEAP_SIZEdecision. The icons are as follows:

Insert picture description here

The large rectangular box is a pile, which configTOTAL_HEAP_SIZEdetermines the size. Each task made TCBand 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_2The heap_1same, a large space is cut into smaller blocks used by the program. the difference lies in:

  1. heap_2 Allow space to be freed
  2. heap_2 The allocation algorithm is implemented instead of direct allocation.

heap_2Will not allocate the remaining space after integrate, to fragmentationbe more sensitive. The distribution process is as follows:

Insert picture description here

Heap_3

Direct use of C mallocand free. At this configTOTAL_HEAP_SIZEfailure, decided to no longer heap size. heap_3The advantage is that thread-safeand scheduler suspension.

Heap_4

And heap_1, heap_2the same principle: the monolithic stack is divided into small blocks used for scheduling. heap_4The remaining small blocks will be integrated to form a large memory block. Used to handle situations where memory request sizes are different. Icon:

Insert picture description here

Heap_5

The Heap_4basis can define a plurality of RAMblock 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 0000beginning is an internal RAM, 0x6000 0000initially outside the RAM . You can only declare the internal RAM size and space in the link script( link file ). Then heap_5declared external RAM space allocated for use by the operating system.

to sum up

  • heap_1 : Only allocate, not release, suitable for always-existing situations
  • heap_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 similar
  • heap_3: C is achieved mallocand freefunctions
  • heap_4 : You can release and integrate the remaining memory blocks, suitable for applications with different memory sizes
  • heap_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_HOOKset to 1.

Reference article

  1. Mastering the FreeRTOS ™Real Time Kernel

Guess you like

Origin blog.csdn.net/lib0000/article/details/112425821