Talking about the application of malloc function in single chip microcomputer

	聊聊 malloc函数 在单片机程序设计中怎么使用

foreword

When I updated the RT-Thread column recently, when it came to memory management, I thought about how to explain this memory management. In fact, when I usually use STM32 as a general product, the malloc function is basically not used, even if the operating system is used, in If the business logic is not complicated, malloc is still not used.

But each embedded RTOS will have its own memory management method. This article will talk about some of my views on the malloc function in microcontroller programming.

This article is not to explain how to use the malloc function in the single-chip microcomputer, but according to the blogger's own understanding, to analyze whether it is necessary to use the function, when and where to use it.

The discussion in this article is in the field of single-chip microcomputers, taking the Cortex-M series core as an example.

1. Introduction to malloc function

The full name of malloc is memory allocation, which is called dynamic memory allocation in Chinese.

Function prototype void *malloc(unsigned int size), professional explanation or apply Baidu Encyclopedia:
insert image description here
for malloc function, all embedded engineers should know, even if they have never used it, they have heard it. Through the above simple description, they can know what it is used for.

Note that in the red box above, malloc opens up a continuous space and returns an address. When the memory is not in use, you need to use a free()function to release the memory.

2. malloc for single chip microcomputer

In our microcontroller programming, most of the C language used, of course, can use the malloc function, but many people can not really understand it.

To understand the malloc function in the microcontroller system, you must first understand where the dynamically allocated memory is!

2.1 Where is the memory requested by the malloc function?

Maybe most people know in the heap! Yes, that's right in the heap.

Then the next question is, where is it stacked in the microcontroller? What is the specific address?

To understand this problem, you have to understand the data storage method of the kernel. Let's take the commonly used STM32 as an example. I have introduced the memory management of STM32 in detail in the following blog post (if you don't understand it, please read this blog post first):

Memory management related to STM32 (memory architecture, memory management, map file analysis)

First, briefly understand the stack of the microcontroller. The text has the following instructions:
insert image description here

If we understand the memory allocation through the blog post recommended above, then we can get the following conclusions, and we can know the exact address of the malloc application space:
insert image description here

2.2 The difference between using and not using malloc

Knowing the address of the malloc application space in the microcontroller, let's take a look at the difference between uses.

Generally in our design, some temporary variables may be initialized in the function. If it is an array, then it will also apply for a memory space. Let's take a look at the difference between using temporary variables and malloc through a picture:
insert image description here

Explained here, I believe that everyone has a deeper understanding of using malloc on the microcontroller. The space he stores is different from the space we often use for local variables, and we know where it is.

As for the single-chip microcomputer or not to use the malloc function? Don't worry, we have to analyze the analysis below.

3. Problems that malloc may encounter

When introducing the working mechanism of malloc in the official Baidu Encyclopedia, there are the following instructions:
insert image description here
Pay attention to the red part in the picture. The simple explanation is that after using more malloc functions, a lot of memory fragments will be generated, and memory will be wasted in vain.

3.1 Memory Fragmentation

What is memory fragmentation?

This kind of professional term has to rely on the omnipotent Baidu (although Baidu Baike's explanation is aimed at a large range, but it is actually the same for single-chip microcomputers):
insert image description here

All the unusable free memory in the system is memory fragmentation.

So how does memory fragmentation come about?

In the above figure, there is actually an explanation of how the fragmentation is generated. The internal fragmentation is due to the architecture of the processor and requires byte alignment. For example, in our single-chip microcomputer, we often have 4-byte alignment and 8-byte alignment, not to mention this. I don't know, I just open a STM32L051 startup file description (link file in the GCC environment):
insert image description here

According to this startup file, we should also be able to know that the stack memory space needs 8-byte alignment, then the memory space we allocate using malloc on STM32 is 8-byte aligned, even if you don't use 8 bytes, The system will also make up for you.

Speaking of this, it is just right to illustrate the first situation of our memory fragmentation, the generation of internal fragments:
insert image description here
then the generation of external fragments, we can also use graphics to represent:
insert image description here
as memory is continuously allocated and released, the entire memory area will be More and more fragments are generated, because some memory is applied for during use, and some of them are released, resulting in some small memory blocks in the memory space. Their addresses are not contiguous and cannot be allocated as a whole block of large memory. Going out, there is enough free memory in the system, but because their addresses are not continuous, they cannot form a continuous complete memory block, which will make the program unable to apply for large memory.

On the single chip microcomputer we use, the problem of fragmentation is particularly obvious, and it is usually not accessible because the general learning test will not encounter complex items.

3.2 Memory Management

Fragmentation occurs with malloc, so is there any way to solve this problem?

Of course there is, and that is memory management.

Memory management is to solve the above-mentioned memory fragmentation problem, how to allocate efficiently and quickly, and release and reclaim memory resources at the appropriate time.

For microcontrollers, if you have the ability, you can design your own way of memory management.

If you use embedded operating systems such as FreeRTOS and RT-Thread, their kernels have their own memory management. This article will not discuss how they manage memory, but it is necessary to understand the idea of ​​​​the operating system.

Take FreeRTOS as an example to illustrate:

There is a macro definition in FreeRTOS configTOTAL_HEAP_SIZE:
insert image description here

The operating system first applies to the system for a large piece of memory, which is managed by the operating system's own memory management methods. For FreeRTOS, there are five memory management methods:

insert image description here
We can choose which one to use when designing, for example:
insert image description here

The requested memory is automatically managed by the operating system. The task stack created by the FreeRTOS operating system uses this piece of memory. At the same time, pvPortMallocapplying for dynamic memory using functions will also be allocated from this piece of memory, because he has a complete set of Memory management method, so compared to our direct use malloc, it can handle the problem of system memory fragmentation very well.

Now that we are talking about this, an additional question is, which configTOTAL_HEAP_SIZEpart of the memory defined by FreeRTOS is located in the memory of the microcontroller?

This can be seen in another blog post of mine: task stack and system stack of embedded RTOS

The memory requested by FreeRTOS belongs to the .bss segment, and the location is shown in the following figure:
insert image description here

For the embedded operating system used by the single-chip microcomputer, they have their own memory management methods, and also provide the dynamic memory application structure. At this time, we use the malloc interface function provided by the operating system to avoid the generation of memory fragmentation. .

Notice! ! The single-chip microcomputer uses an operating system with memory management, and the system will provide relevant APIs, such as the functions of FreeRTOS and the pvPortMallocfunctions of RT-Thread rt_malloc.
If you use the C library malloc, you will still apply for memory from the system heap! !

For high-end single-chip microcomputers, there are MMU (memory management unit) modules, such as the Cortex-A series. With MMU, you can run linux, so memory management is also a must.

Fourth, the conclusion (use or not?)

This article is a detailed analysis of the use of malloc function on the microcontroller. We know where the malloc function applies for the memory space, and we also know how the memory fragmentation is generated.

Back to our original question, in the field of microcontrollers, to use or not to use the malloc function?

After reading the article, this question probably does not need me to answer directly:

In terms of project complexity:

If you run bare metal to do some small projects, it is not recommended to use it if you do not have your own memory management method and it is not necessary. At the same time, in order to save memory, you can set the heap to be small (leave a little for the C library functions that may be called).

If you run the operating system, the operating system has perfect memory management, and you can happily use the mallocinterface functions of the operating system.
But if you do some small projects, you can do without it.

If you run bare metal to do some big projects? ? ? ? I personally don't recommend...

From the size of the chip RAM used:

If the chip memory you choose is relatively small, more than 10K or even a few K, still use static memory local variables, because projects that can use small memory will not be too complicated, such as IoT sensor single-product projects.

If the selected chip memory is larger than MB, you can still try to use malloc dynamic memory allocation, but the premise is that there is still memory management.

But in the end, I have to say that with the development of the current single-chip microcomputer, the memory is getting bigger and bigger. Although it is not recommended to use the malloc function for small single-chip microcomputer projects, after we use the operating system, we must learn to use dynamic memory allocation, because when we do The project is becoming more and more complex, there are more and more threads, and we define more and more local variables. Even if we can continue to increase the size of the system stack, this is not a reasonable solution after all.
We should learn to use dynamic memory application reasonably, in order to move to a higher place in the future~

There is no need to drill down, if the project is simple but just want to use it. For example, I use malloc to apply for dynamic memory for a function, and there is no memory management. How do I use it? This situation is the same whether it is used or not, see if you are happy, there is no need to struggle!

Thanks!

Guess you like

Origin blog.csdn.net/weixin_42328389/article/details/124124224