How to tailor the source code of the operating system - transplanting the memory management module of FreeRTOS to the ARMV8 bare chip

How to trim the operating system source code

The requirement scenario for this article is to transplant the memory management module for the processor IP that lacks standard library implementation, that is, to deploy the malloc()and free()functions in the C standard library for the bare chip.

The specific method is to cut out the necessary source code from the memory management component of the operating system and adapt it to the development environment of the target processor (SDK/IDE/CMAKE project subdirectory).

1 Determining requirements - understanding memory management/heap management

1.1 Memory management scheme in the C standard library

The C standard library provides a set of memory management functions for dynamic memory allocation and release operations in C programs. These functions mainly include malloc, calloc, realloc and free.

malloc function: The malloc function is used to allocate a memory block of a specified size and return a pointer to the memory block. Its function prototype is:

void* malloc(size_t size);

It accepts a parameter size, indicating the size of the memory space to be allocated (in bytes). The malloc function allocates a continuous block of memory in the heap memory and returns a pointer to the starting address of the memory block.

calloc function: The calloc function is also used to allocate a memory block of a specified number and size, and returns a pointer to the memory block. Unlike malloc, calloc initializes every byte in the allocated memory block to 0. Its function prototype is:

void* calloc(size_t num, size_t size);

The num parameter indicates the number of elements that need to be allocated, and the size parameter indicates the size of each element (in bytes). The calloc function allocates a memory block of size num * size in the heap memory and returns a pointer to the starting address of the memory block.

realloc function: The realloc function is used to resize a previously allocated memory block. Its function prototype is:

void* realloc(void* ptr, size_t size);

The ptr parameter is a pointer to a memory block previously allocated by malloc or calloc, and the size parameter indicates the size (in bytes) that needs to be adjusted. The realloc function re-allocates the memory block according to the new size and returns a pointer to the starting address of the re-allocated memory block. If the memory block cannot be reallocated, the realloc function may create a new memory block and copy the data of the original memory block to the new memory block.

free function: The free function is used to release the memory block previously allocated by malloc, calloc or realloc function. Its function prototype is:

void free(void* ptr);

The ptr parameter is a pointer to a previously allocated block of memory. By calling the free function, the memory block will be marked as free and can be allocated again for other memory needs.

1.2 Demand tailoring

Bare chip programs are limited by memory resources, and are generally designed using static allocation methods. Only basic dynamic memory management methods need to be provided when transplanting some peripheral drivers, and there is little need for new pre-allocated dynamic memory. . So reallocthe and callocfunctions can be omitted, so that our task load is reduced by half.

2 Find the wheel - learn from the operating system

The operating system is an abstraction of hardware. Most of the requirements on the bare chip can be found in the source code of the operating system. So why reinvent the wheel and just grab the wool of the operating system.

2.1 Memory management scheme in FreeRTOS

FreeRTOS provides several heap management schemes. The complexity and functions of these schemes vary, and they are suitable for different demand scenarios. See the figure below for details.
insert image description here
In summary, FreeRTOS provides us with 5 optional implementations of memory management modules in the source code directory Source/Portable/MemMang:

  • heap_1: Minimalist version, does not support memory release (no free function)
  • heap_2: supports freeing, but does not merge freed memory blocks
  • heap_3: supports thread-safe malloc and free functions
  • heap_4: Merge freed memory blocks to avoid memory fragmentation
  • heap_5: supports allocation across multiple memory blocks on the basis of 4

Here we choose according to our own needs. This article chooses heap_2 transplantation, because the basic functions are comprehensive and simple enough.

2.2 Pull source code

Find Source/Portable/MemMang/heap2.c in the source tree, as shown below.
insert image description here
When you open it, you can see that the allocation and release functions are within reach, named pvPortMallocand vPortFreerespectively, and added to our project, and then take a closer look at the dependencies of this source file, extract the dependencies from the source tree, and discard unnecessary files. The memory management module is stripped from the operating system.

2.3 Stripping dependencies

heap_2.c contains two FreeRTOS-related header files - FreeRTOS.h and task.h, the latter is a statement related to the task scheduler, we obviously don't need it, just delete it directly. FreeRTOS is a macro definition of some configuration items. We cut out the memory management-related ones, and there is no need to keep the entire FreeRTOS.h file.

insert image description here

Then there is a macro definition used to make the managed memory space size meet the memory alignment requirements:

/* A few bytes might be lost to byte aligning the heap start address. */
#define configADJUSTED_HEAP_SIZE    ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT )

Both configTOTAL_HEAP_SIZE and portBYTE_ALIGNMENT require us to manually #define
insert image description here
heap_2.c and use a macro definition portBYTE_ALIGNMENT_MASK:
insert image description here
originally in FreeRTOS.h, we added it to portmacro.h:
insert image description here
the rest is some basic type replacements, and we put them in portmacro In the .h file:
insert image description here
projdefs.h is also required, and there are macros of trueand in it:false
insert image description here

2.4 Available source code

Github repository: memManPort

3 tests

You can use the following demo to test the usability of the transplant results. As long as the pb and pc values ​​are consistent, it is basically correct.
insert image description here

Guess you like

Origin blog.csdn.net/qq_33904382/article/details/132130018