Memory allocation of C program based on ubuntu and stm32

1, c language program memory allocation

  • 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.
  • 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.
  • 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.
  • Text constant area
    Store constant strings. When the program ends, the constant string is released by the system.
  • 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.

2, C program memory allocation under ubuntu

  • c procedure
#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] = "lyy";
    //Define constant string
    char *var1 = "1234567890";
    char *var2 = "qwertyuiop";
    //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;
}

  • Operation effect
  • Memory allocation analysis
    Through the running results, it can be found that the address values of Ubuntu in stack area and heap area increase 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.

3, C program memory allocation under STM32

  • CUBEMX has built projects:
    Set serial port

    Set clock:
  • Modify main function
#include "main.h"
#include "usart.h"
#include "gpio.h"
#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");
}
 
 
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
 
/* USER CODE END Includes */
 
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
 
/* USER CODE END PTD */
 
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
 
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
 
/* USER CODE END PM */
 
/* Private variables ---------------------------------------------------------*/
 
/* USER CODE BEGIN PV */
 
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
 
/* USER CODE END PFP */
 
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
 
/* USER CODE END 0 */
 
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
 
  /* USER CODE END 1 */
 
  /* MCU Configuration--------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
 int a=2;
	static int inits_local_c=2, uninits_local_c;
    int init_local_d = 1;
    output(a);
    char *p;
    char str[10] = "lyy";
    //Define constant string
    char *var1 = "1234567890";
    char *var2 = "qwertyuiop";
    //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;
 
  /* USER CODE END 3 */
}
  • options settings:
    Click target and select use microlib
  • Compile and generate hex file

After compilation, we can see that there are four Code segment sizes: Code, RO data, RW data and Zi data. 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.
We need to know the usage of RAM and ROM, which can be calculated using the following formula:
**RAM = RW-data + ZI-data
ROM = Code + RO-data + RW-data
Flash=Code + RO Data + RW Data
This is the size of each segment that can be obtained after MDK compilation, and the corresponding FLASH and RAM size can also be obtained. However, there are two data segment heaps and stacks that will also occupy RAM, but only when the program is running.

  • Serial output effect

  • Memory allocation analysis (storage location of stm32 data)

  • RAM (random access memory)
    The stored contents can be accessed randomly by 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). Stack, heap and global area (. bss segment and. Data segment) are stored in RAM.

  • ROM (read only memory)
    You can only read data from it, 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. The contents of code area and constant area are not allowed to be modified, so they are stored in ROM.

  • View stm32 address assignment

① By default, the allocated ROM area starts with 0x8000000 and the size is 0x80000. Then this area is a read-only area and cannot be modified, that is, the stored code area and constant area
② The default allocated RAM area is an area starting from 0x20000000 and with a size of 0x10000. This area is a read-write area and stores static area, stack area and heap area.

4, Summary

  • Through the analysis of the memory allocation problem of c program based on different platforms, we know that the address value of Ubuntu in stack area and heap area increases 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.

reference material

Memory allocation of C program based on ubuntu, raspberry pie and stm32

Keywords: C Ubuntu stm32

Added by Bozebo on Sun, 26 Dec 2021 14:08:15 +0200