Follow+Star Public Account Number, don’t miss out on exciting content
Author | strongerHuang
WeChat Public Account | Embedded Column
The stack is very important for programs; it plays a significant role in enabling programs to run quickly. But do you understand the stack?
1Introduction
We all know that the stack is located in RAM, and currently, the RAM of MCUs is relatively large (tens to hundreds of K), so the allocated stack is also sufficiently large, which is why many people do not pay much attention to the size of the stack.
However, in the past, the RAM of MCUs was relatively small, sometimes even less than 1K, so engineers were more concerned about the size of the stack.For small projects, we might not need to worry about the stack size.However, if the project is large, you need to pay attention; if your stack size is set improperly, it is very likely to lead to a Fault.To know how large the stack should be, you need to understand the role of the stack. Let’s further explore the stack.
2Basic Knowledge about the Stack
Let’s first look at two classic pieces of knowledge.
1. Memory Allocation of ProgramsA program compiled by C/C occupies memory divided into the following parts:Stack: Automatically allocated and released by the compiler, storing function parameter values, local variable values, etc. Its operation is similar to the stack in data structures.Heap: Generally allocated and released by the programmer; if the programmer does not release it, it may be reclaimed by the OS at the end of the program. Note that it is different from the heap in data structures, and its allocation method is similar to a linked list.Global Area (Static): Global and static variables are stored together; initialized global and static variables are in one area, while uninitialized global and static variables are in an adjacent area. Released by the system after the program ends.String Constant Area: Constant strings are stored here and released by the system after the program ends.Program Code Area: Stores the binary code of function bodies.2. Classic Example Program
int a = 0; // Global Initialization Areachar *p1; // Global Uninitialized Areamain(){ int b; // Stack char s[] = "abc"; // Stack char *p2; // Stack char *p3 = "123456"; //123456\0 in Constant Area, p3 on Stack. static int c =0; // Global (Static) Initialization Area p1 = (char *)malloc(10); p2 = (char *)malloc(20); // Allocated 10 and 20 bytes in Heap. strcpy(p1, "123456"); //123456\0 in Constant Area, compiler may optimize it with p3's "123456" to one place.}
3Discussing the Stack in STM32 Development
From the above description, we can see how the heap and stack are occupied in the code.
Many people may still not understand, so let’s discuss the content related to the stack in the STM32 development process.
1. How to Set the Stack Size of STM32?
This issue is discussed in the article 《What is the Startup Process of STM32?》, which explains how to set the stack size in MDK-ARM, IAR EWARM, and using STM32CubeMX.
2. Stack
The default setting for STM32F1 is 0x400, which is 1K in size.
Stack_Size EQU 0x400
Local Variables in Function Body:
void Fun(void){ char i; int Tmp[256]; //...}
The local variables occupy a total of 256*4 + 1 bytes of stack space.
Therefore, when there are many local variables in a function, you need to be cautious about whether it exceeds the configured stack size.
Function Parameters:
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
It is important to emphasize that: passing pointers only occupies 4 bytes, while passing structures will occupy the size of the structure.
Note: In function nesting and recursion, the system will still occupy stack space.
3. Heap
Heap_Size EQU 0x200
The default setting is 0x200 (512) bytes.Most of us should rarely use malloc to allocate heap space.Although data on the heap can be accessed as long as the programmer does not release the space, forgetting to release heap memory can lead to memory leaks and even fatal potential errors.
4Extension: Analyzing RAM Usage in MDK
Those who often debug online may analyze some low-level content. Here, we will analyze the RAM usage issue in MDK-ARM.
After compiling in MDK, there will be a segment of RAM size information:
This size is 0x668, and during debugging, the following may occur:
The MSP is the Main Stack Pointer, which generally points to the location after reset; the reset actually points to the top of the stack:
And the MSP points to address 0x20000668, which is offset from 0x20000000 by 0x668.
To see which areas occupy RAM, refer to the content in the map file at the 【Image Symbol Table】 section:
Of course, for a detailed analysis of the map file, you can refer to my series tutorial 《Keil Series Tutorial 12: Comprehensive Analysis of Map Files》.
There is actually much more knowledge to expand on regarding stacks, such as stack push and pop, growth direction (upward or downward), and endianness.
———— END ————
Reply with 『MCU』『Microcontroller』『Keil Series Tutorial』 to read more related articles.
Follow the WeChat Public Account 『Embedded Column』, check the bottom menu for more content, reply “Join Group” to join the technical exchange group according to the rules.
Click “Read the Original” to see more shares, and feel free to share, bookmark, like, and view.