Write a C program, review concepts such as global constants, global variables, local variables, static variables, heap, and stack, and program and verify them in Ubuntu (x86) system and STM32 (Keil) respectively.

Table of Contents

1. Global variables and local variables

2. Heap & stack

3. Verify using programs

4. Summary


1. Global variables and local variables

global variables
Variables defined outside all functions are called global variables, and their scope is the entire program by default, that is, all source files.

local variables
A variable defined inside a function is called a local variable. Its scope is limited to the inside of the function. Its definition will be ignored when leaving the function, and an error will be reported when used outside the function.

The difference between the two

Scope:

Global variables: Global variables can be accessed anywhere in the program, that is, their scope is the entire program. They are usually defined at the top of the program and exist throughout the execution of the program.
Local variables: Local variables can only be accessed within the specific scope in which they are located. For example, local variables defined inside a function can only be used within that function, and their scope is limited to that function.
Accessibility:

Global variables: Global variables can be accessed throughout the program, including within functions. Functions can access global variables directly without any additional declaration.
Local variables: Local variables can only be accessed within the scope in which they are defined. Local variables cannot be directly accessed by other functions or the global scope.
life cycle:

Global variables: Global variables are created when the program starts executing and are not destroyed until the program ends. Their life cycle is the same as the execution cycle of the entire program.
Local variables: Local variables are allocated memory when the scope in which they are located is created, and are automatically destroyed when the scope ends. Whenever a function executes, local variables are created and destroyed.
Conflict risk:

Global variables: Due to their high accessibility, global variables may be accessed and modified by multiple functions at the same time. This can lead to unexpected changes to variables and value conflicts.
Local variables: Local variables are only valid within the scope in which they are defined and will not conflict with other functions or global variables. This increases code maintainability and reliability.
memory location

The memory location of global variables in C is the heap area, while local variables are located in the stack area.

二.Stack&Stack

1. Stack in STM32
The microcontroller is an integrated circuit chip that integrates functions such as CPU, RAM, ROM, various I/O ports, interrupt system, timer/counter, etc. The CPU includes various bus circuits, calculation circuits, logic circuits, and various registers.

stm32 has general registers R0-R15 and some special function registers, including the stack pointer register.
When stm32 is running the program normally, and an interrupt occurs, the CPU needs to push the value in the register onto the stack into RAM, and then store the address of the data in the stack register.
When the interrupt processing is completed and exited, the data is popped out of the stack into the previous register. This is done automatically in the C language.

2. Program memory allocation
The memory occupied by general programs is divided into the following parts:

1. Stack area (stack) – automatically allocated and released by the compiler, storing function parameter values, local variable values, etc. It operates like a stack in a data structure.

2. Heap area (heap) – Generally allocated and released by the programmer. If the programmer does not release it, it may be recycled by the OS when the program ends. It is different from the heap in the data structure, and the allocation method is similar to a linked list.

3. Global area (static area) (static) – global variables and static variables are stored together. Initialized global variables and static variables are in the same area, and uninitialized global variables and uninitialized static variables are in the same area. Another adjacent area. There is system release after the program ends.

4. Literal constant area-constant strings are placed here. Released by the system after the program ends

5. Program code area-stores the binary code of the function body.

//main.cpp
int a = 0; //global initialization area
int a = 0; //global initialization area
char *p1; //Global uninitialized area
main() {
    int b; //stack
    char s[] = "abc"; //stack
    char *p2; //stack
    char *p3 = "123456"; //123456\0 is in the constant area and p3 is on the stack.
    static int c = 0; //Global (static) initialization area
    p1 = (char *)malloc(10);
    p2 = (char *)malloc(20);
    //The allocated areas of 10 and 20 bytes are in the heap area.
    strcpy(p1, "123456"); //123456\0 is placed in the constant area, and the compiler may optimize it into the same place as the "123456" pointed to by p3.
}

In an STM32 program code, from the high memory address to the low memory address, the stack area, heap area, global area (static area), constant area, and code area are distributed in order. Among them, the high address in the global area is distributed with the .bss section, and the low address is distributed The address is distributed with .data segments.

This part of the content is introduced in detail through the following mind map:

#include <stdio.h>
 
static unsigned int val1 = 1; //val1 is stored in the .data section
 
unsigned int val2 = 1; //Initialized global variables are stored in the .data section
 
unsigned int val3; //Uninitialized global variables are stored in the .bss section
 
const unsigned int val4 = 1; //val4 is stored in .rodata (read-only data segment)
 
 
unsigned char Demo(unsigned int num) // num is stored in the stack area
{
char var = "123456"; // var is stored in the stack area, "123456" is stored in the constant area
\t
unsigned int num1 = 1; // num1 is stored in the stack area
\t
static unsigned int num2 = 0; // num2 is stored in the .data section
 
    const unsigned int num3 = 7; //num3 is stored in the stack area
 
void *p;
\t
p = malloc(8); //p is stored in the heap area
\t
free(p);
 
    return 1;
}
 
void main()
{
unsigned int num = 0;
num = Demo(num); //The return value of the Demo() function is stored in the stack area.
}

3. Use program for verification

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("\\
");
}

int main()
{
//Define local variables
int a=2;//stack
static int inits_local_c=2, uninits_local_c;
    int init_local_d = 1;//stack
    output(a);
    char *p;//stack
    char str[20] = "constellation";//stack
    //Define constant string
    char *var1 = "1234567890";
    char *var2 = "abcdefghij";
    //Dynamic allocation - heap area
    int *p1=malloc(4);
    int *p2=malloc(4);
    //freed
    free(p1);
    free(p2);
    printf("Stack area-variable address\\
");
    printf(" a:%p\\
", & amp;a);
    printf("init_local_d:%p\\
", & amp;init_local_d);
    printf(" p:%p\\
", & amp;p);
    printf(" str:%p\\
", str);
    printf("\\
Heap area-dynamic application address\\
");
    printf(" %p\\
", p1);
    printf(" %p\\
", p2);
    printf("\\
Global area - global variables and static variables\\
");
    printf("\\
.bss section\\
");
    printf("Global external no initial value uninit_global_a: %p\\
", & amp;uninit_global_a);
    printf("static external no initial value uninits_global_b: %p\\
", & amp;uninits_global_b);
    printf("static internal no initial value uninits_local_c: %p\\
", & amp;uninits_local_c);
    printf("\\
.data segment\\
");
    printf("There is an initial value outside the global init_global_a: %p\\
", & amp;init_global_a);
    printf("static external initial value inits_global_b: %p\\
", & amp;inits_global_b);
    printf("Static internal initial value inits_local_c: %p\\
", & amp;inits_local_c);
    printf("\\
Literal constant area\\
");
    printf("Literal constant address: %p\\
",var1);
    printf("Literal constant address: %p\\
",var2);
    printf("\\
code area\\
");
    printf("Program area address: %p\\
", & amp;main);
    printf("Function address: %p\\
", & amp;output);
    return 0;
}

Implemented on ubuntu

It is not difficult to see that in Ubuntu, except for the .bss section, the memory allocation in all other areas continues to grow from top to bottom.

Verify in keil

code

#include "sys.h"
#include "usart.h"
#include "delay.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 initialization variable
static int uninits_global_b;//Static uninitialized variables
void output(int a)
{
printf("the result is:");

printf("\\
");
}

int main(void)
{
u16 t; u16 len; u16 times=0;
Stm32_Clock_Init(9); //System clock setting
delay_init(72); //Delay initialization
uart_init(72,115200); //The serial port is initialized to 115200
\t
\t
\t
  while(1)
{
int a=2;
static int inits_local_c=2, uninits_local_c;
    int init_local_d = 1;
    output(a);
    char *p;
    char str[20] = "constellation";
    //Define constant string
    char *var1 = "1234567890";
    char *var2 = "abcdefghij";
    //Dynamic allocation
    int *p1=malloc(4);
    int *p2=malloc(4);
    //freed
    free(p1);
    free(p2);
    printf("Stack area-variable address\\
");
    printf(" a:%p\\
", & amp;a);
    printf("init_local_d:%p\\
", & amp;init_local_d);
    printf(" p:%p\\
", & amp;p);
    printf(" str:%p\\
", str);
    printf("\\
Heap area-dynamic application address\\
");
    printf(" %p\\
", p1);
    printf(" %p\\
", p2);
    printf("\\
Global area - global variables and static variables\\
");
    printf("\\
.bss section\\
");
    printf("Global external no initial value uninit_global_a: %p\\
", & amp;uninit_global_a);
    printf("static external no initial value uninits_global_b: %p\\
", & amp;uninits_global_b);
    printf("static internal no initial value uninits_local_c: %p\\
", & amp;uninits_local_c);
    printf("\\
.data segment\\
");
    printf("There is an initial value outside the global init_global_a: %p\\
", & amp;init_global_a);
    printf("static external initial value inits_global_b: %p\\
", & amp;inits_global_b);
    printf("Static internal initial value inits_local_c: %p\\
", & amp;inits_local_c);
    printf("\\
Literal constant area\\
");
    printf("Literal constant address: %p\\
",var1);
    printf("Literal constant address: %p\\
",var2);
    printf("\\
code area\\
");
    printf("Program area address: %p\\
", & amp;main);
    printf("Function address: %p\\
", & amp;output);

if(USART_RX_STA &0x8000)
{
len=USART_RX_STA & amp;0x3FFF;//Get the length of data received this time
\t\t\t
for(t=0;t<len;t + + )
{
USART1->DR=USART_RX_BUF[t];
while((USART1->SR & amp;0X40)==0);//Waiting for the sending to end
}
\t\t\t
USART_RX_STA=0;
}else
{
times + + ;
\t\t
delay_ms(100);
}
}
return 0;
}



By running As a result, it can be found that the address value of Ubuntu’s stack area and heap area increases from top to bottom. The address value of stm32’s stack area decreases from top to bottom, and the heap area increases from top to bottom. From the perspective of each area, the address value gradually decreases from top to bottom, that is, the address of the stack area is at a high address, and the address of the code area is at a low address.

Four. Summary

Have a better understanding of the memory allocation of C programs, know what parts of a C program’s memory should be included, and then learn more about stm32 serial port issues

References: [Embedded 18] Program memory allocation issues (stack, local global variables, etc.) under Ubuntu and stm32_Ubuntu software uses memory locations_Puffy Jar’s Blog-CSDN Blog

STM32 variable storage location analysis (according to address analysis)_Where are stm32 local variables stored – CSDN Blog

Memory allocation problem of C program based on ubuntu, Raspberry Pi and stm32_Raspberry Pi improves memory allocation of program running-CSDN Blog