Memory allocation of C program - Ubuntu and STM32

Posted by f8ball on Thu, 23 Dec 2021 14:21:52 +0100

1, Memory allocation of C program

  1. stack area
    It is automatically allocated and released by the compiler to store the parameter values of functions and the values of local variables. Its operation is similar to the stack in the data structure.
  2. heap
    Generally, it is allocated and released by the programmer. If the programmer does not release it, it may be recycled by the OS at the end of the program. It is different from the heap in the data structure, and the allocation method is similar to the linked list.
  3. Global area (static area)
    Global variables and static variables are stored together. Initialized global variables and static variables are in one area, and uninitialized global variables and uninitialized static variables are in another adjacent area. When the program ends, the variable is released by the system.
  4. Text constant area
    Store constant strings. When the program ends, the constant string is released by the system.
  5. Program code area
    Store the binary code of the function body.

Normal programs are usually divided into three parts: program segment, data segment and stack.
The program segment contains the machine code and read-only data of the program. This segment is usually read-only, and its write operation is illegal.
The data segment is the static data in the program.
A stack is a contiguous block in memory. A register (SP) called stack pointer points to the top of the stack. At the bottom of the stack is a fixed address. The stack has a feature of last in first out. That is, the data put later is taken out first. It supports two operations, PUSH and POP. PUSH is to put the data at the top of the stack, POP is to take the data at the top of the stack. Dynamic data is stored in the stack.

Storage area diagram

2, Ubuntu authentication

2.1 code

#include <stdio.h>
#include <stdlib.h>
//Define global variables
int init_global_a = 1;
int uninit_global_a;
static int inits_global_b = 2;
static int uninits_global_b;
void output(int a)
{
	printf("hello");
	printf("%d",a);
	printf("\n");
}

int main( )
{   
	//Define local variables
	int a=2;
	static int inits_local_c=2, uninits_local_c;
    int init_local_d = 1;
    output(a);
    char *p;
    char str[10] = "mona";
    //Define constant string
    char *var1 = "1234567890";
    char *var2 = "abcdefj";
    //Dynamic allocation
    int *p1=malloc(4);
    int *p2=malloc(4);
    //release
    free(p1);
    free(p2);
    printf("Stack area-Variable address\n");
    printf("                a : %p\n", &a);
    printf("                init_local_d: %p\n", &init_local_d);
    printf("                p: %p\n", &p);
    printf("              str: %p\n", str);
    printf("\n Heap area-Dynamic application address\n");
    printf("                   %p\n", p1);
    printf("                   %p\n", p2);
    printf("\n Global area-Global and static variables\n");
    printf("\n.bss paragraph\n");
    printf("Global external no initial value uninit_global_a: %p\n", &uninit_global_a);
    printf("Static external no initial value uninits_global_b: %p\n", &uninits_global_b);
    printf("Static internal no initial value uninits_local_c: %p\n", &uninits_local_c);
    printf("\n.data paragraph\n");
    printf("Global external initial value init_global_a: %p\n", &init_global_a);
    printf("Static external initial value inits_global_b: %p\n", &inits_global_b);
    printf("Static internal initial value inits_local_c: %p\n", &inits_local_c);
    printf("\n Text constant area\n");
    printf("Literal constant address     : %p\n",var1);
    printf("Literal constant address     : %p\n",var2);
    printf("\n Code area\n");
    printf("Program area address       : %p\n",&main);
    printf("Function address         : %p\n",&output);
    return 0;
}

2.2 verification

The command is as follows:

sudo nano text.c

Enter the password to enter the edit text C page


Compile text c:

gcc text.c -o text
./text



It can be seen that in Ubuntu, the variable address value of the stack area gradually increases from top to bottom, and so does the dynamic application address of the heap area.

3, STM32 verification

3.1 establishment of the project

Use STM32cubeMX to establish a project. The specific operations are as follows: STM32 serial communication based on MDK5

Simply put, configuration is

  • SYS–>Debug : Serial Wire
  • RCC–>HES : Crystal/Ceramic Resonator
  • USART1–>Mode : Asynchronous

3.2 add code

  1. Redirect printf function
    In USART Add code to C:
// Redirection function
include<stdio.h>
int fputc(int ch,FILE *f)
{
    uint8_t temp[1]={ch};
    HAL_UART_Transmit(&huart1,temp,1,2);        //UartHandle is the handle of the serial port
}


2. Modify main c
Add header files in the header and define global variables

#include <stdio.h>
#include <stdlib.h>
//Define global variables
int init_global_a = 1;
int uninit_global_a;
static int inits_global_b = 2;
static int uninits_global_b;
void output(int a)
{
	printf("hello");
	printf("%d",a);
	printf("\n");
}


while statement found:

Modify the whole block code as follows:

//Define local variables
	int a=2;
	static int inits_local_c=2, uninits_local_c;
    int init_local_d = 1;
    output(a);
    char *p;
    char str[10] = "mona";
    //Define constant string
    char *var1 = "1234567890";
    char *var2 = "abcdefj";
    //Dynamic allocation
    int *p1=malloc(4);
    int *p2=malloc(4);
    //release
    free(p1);
    free(p2);
    printf("Stack area-Variable address\n");
    printf("                a: %p\n", &a);
    printf("                init_local_d: %p\n", &init_local_d);
    printf("                p: %p\n", &p);
    printf("              str: %p\n", str);
    printf("\n Heap area-Dynamic application address\n");
    printf("                   %p\n", p1);
    printf("                   %p\n", p2);
    printf("\n Global area-Global and static variables\n");
    printf("\n.bss paragraph\n");
    printf("Global external no initial value uninit_global_a: %p\n", &uninit_global_a);
    printf("Static external no initial value uninits_global_b: %p\n", &uninits_global_b);
    printf("Static internal no initial value uninits_local_c: %p\n", &uninits_local_c);
    printf("\n.data paragraph\n");
    printf("Global external initial value init_global_a: %p\n", &init_global_a);
    printf("Static external initial value inits_global_b: %p\n", &inits_global_b);
    printf("Static internal initial value inits_local_c: %p\n", &inits_local_c);
    printf("\n Text constant area\n");
    printf("Literal constant address     : %p\n",var1);
    printf("Literal constant address     : %p\n",var2);
    printf("\n Code area\n");
    printf("Program area address       : %p\n",&main);
    printf("Function address         : %p\n",&output);


3. Configure Target
Click "magic wand" to enter the project configuration

3.3 compiling and burning

Select the generated hex file to burn:

Open the serial port debugging assistant:


It can be seen that in stm32, the variable address value of the stack area gradually decreases from top to bottom, while the dynamic application address value of the heap area gradually increases from top to bottom.

Comparison and summary: the address values of Ubuntu stack area and heap area increase from top to bottom, the address value of stm32 stack area decreases from top to bottom, and the heap area increases from top to bottom. From each area, the address value decreases gradually from top to bottom, that is, the address of the stack area is the high address and the address of the code area is the low address.

4, Memory analysis based on STM32

4.1 memory distribution

In an STM32 program code, stack area, heap area, global area (static area), constant area and code area are successively distributed from high memory address to low memory address, in which. bss segment is distributed in high address and. data segment is distributed in low address.
The total distribution is as follows:

Memory address
Stack area
Heap area
. bss segment
. data segment
Constant area
Code area
  • stack area
    Temporarily created local variables are stored in the stack area;
    When a function is called, its entry parameters are stored in the stack area;
    When the function returns, its return value is stored in the stack area;
    The local variables defined by const are stored in the stack area.
  • heap
    Heap area is used to store memory segments dynamically distributed during program operation, which can be increased or decreased;
    malloc and other functions can be used to dynamically distribute memory;
    The memory distributed by malloc function must be released with free, otherwise it will cause memory leakage.
  • Global area (static area)
    The global area has bss segment and data segment, readable and writable.
    . bss segment
    Uninitialized global variables are stored in bss segment;
    Global variables initialized to 0 and static variables initialized to 0 are stored in bss segment;
    . bss segment does not occupy executable file space, and its contents include operating system initialization.
    . data segment
    The initialized global variables are stored in the data segment;
    Static variables are stored in data segment;
    . The data section occupies the executable file space, and its content includes program initialization;
    The global variables defined by const are stored in rodata section.
  • Constant area
    The string is stored in the constant area;
    The contents of the constant area cannot be modified.
  • Code area
    The program execution code is stored in the code area.
    String constants may also be stored in the code area.

4.2 storage location of different data

Ram is also called random access memory. The stored contents can be accessed by random reading and writing instructions. The data stored in RAM will be lost during power failure, so it can only be stored during startup and operation.
RAM can be divided into two types: Dynamic RAM(DRAM) and Static RAM(SRAM).

ROM, also known as read-only memory, can only read data from it, but can not write data arbitrarily. Compared with RAM, ROM has the disadvantage of slow reading and writing speed. However, because it has the advantage that the data can remain unchanged after power failure, it is often used to store one-time written programs and data. For example, the chip of the main BIOS program is ROM memory.

From the previous analysis, we know that the contents of code area and constant area are not allowed to be modified, and ROM (STM32 is Flash Memory) is not allowed to be modified. Therefore, the contents of code area and constant area are compiled and stored in ROM; while stack, heap and global area (. bss segment and. data segment) are stored in RAM.

4.3 STM32 address allocation

  • On the Target page of Option, you can see the address allocation of STM32 as follows:

    The address allocation of ROM starts from 0x8000000 and the whole size is 0x10000. This part is used to store code area and text constant area; The address allocation of RAM starts from 0x20000000 and its size is 0x5000. This area is used to store stack, heap and global area (. bss section and. data section).

  • After compiling the project, you can see the size of Code, RO data, RW data and Zi data on the Build Output page.

    Where Code is the Code occupation size, RO data is a read-only constant, RW data is an initialized readable and writable variable, and Zi data is an uninitialized readable and writable variable.

  • If you want to know how RAM and ROM are used, you can use the following formula:
    RAM = RW-data + ZI-data
    ROM = Code + RO-data + RW-data

5, Summary

Through this verification experiment, we have a certain understanding of the memory allocation of C program and understand the specific allocation content. By comparing Ubuntu with STM32, it is found that the address value changes in the region under different systems are also different. Finally, after using Keil for such a long time, the Program Size of the output window has a sense of existence for the first time. I used to know that it is the value of memory occupation, but now I know its specific definition!

6, References

https://blog.csdn.net/qq_43279579/article/details/110308101
https://my.oschina.net/mizhinian/blog/4472814
https://blog.csdn.net/qq_54496810/article/details/121923313

Topics: C Ubuntu Embedded system stm32