Review of variable storage and learning and practice of Clion editor

1. Experimental requirements

1. Write a C program, revisit the concepts of global variables, local variables, heaps, stacks, etc., and program and verify in Ubuntu (x86) system and STM32 (Keil) respectively (STM32 printf information through the serial port to the host computer serial port assistant) . Summarize the allocation addresses of variables such as heap, stack, global, and local variables in C programs under Ubuntu and stm32, and conduct comparative analysis.
2. Install Clion2021, and use a new embedded software development kit (replacing Keil) to complete the stm32F103 LED lighting program.

Second, variable storage review

1. Memory allocation

(1) Brief description of memory attributes

静态分配内存:在程序编译和链接时就确定好的内存
动态分配内存:在程序加载、调入、执行的时候分配/回收的内存

(2) Brief description of memory partition

Stack area (stack): automatically allocated and released by the compiler to store function parameters and local variables (auto type). It operates like a stack in a data structure.
Heap area (heap): The program dynamically allocates and releases space. 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. (Different from the heap in the data structure, the allocation method is similar to a linked list)
Global/static area (static): The storage of global variables and static variables is put together, and initialized global variables and static variables are in the same area, uninitialized Global variables and uninitialized static variables are in another adjacent area. (When the program ends, the variable is released by the system)
Literal constant area: store constant strings (when the program ends, the constant strings are released by the system)
Program code area: store the binary code of the function body
Note:
a normal program is stored in memory It is usually divided into three parts: program segment, data segment and stack.
Program segment: The machine code of the program, read-only data, usually read-only, and writing to it is illegal.
Data segment: Static data in the program.
Stack: A contiguous block in memory. Dynamic data is stored through the stack. The stack pointer register (SP) points to the top of the stack. The bottom of the stack is a fixed address, which is characterized by last-in-first-out, that is, the data put in later is taken out first. It supports PUSH, POP operations. PUSH is to put data on the top of the stack, and POP is to take out the data on the top of the stack.
insert image description here
insert image description here

(3) Partition comparison

Note:
① As the number of function call layers increases, the function stack frame extends to the low address of the memory block by block.
② As the number of function call layers in the process decreases (that is, the return of each function call), the stack frame will be abandoned piece by piece and retracted to the high address of the memory.
③ The size of the stack frame of each function varies with the nature of the function, and is determined by the number of local variables of the function.
④ The process's dynamic application for memory occurs in the Heap (heap). As the amount of memory dynamically allocated to the process by the system increases, the Heap (heap) may extend to high or low addresses, which depends on different CPUs. Realization, but generally speaking, it grows towards the high address of the memory.
⑤ When the growth of the uninitialized data area (BSS) or Stack (stack area) exhausts the free memory allocated by the system to the process, the process will be blocked and re-scheduled by the operating system with a larger memory module .

insert image description here

(4) STM32 data storage location

The contents of the code area and constant area are compiled and stored in ROM; the stack, heap, and global area (.bss segment, .data segment) are stored in RAM.
insert image description here

2. Programming for verification

(1) Free authentication

[1] The code is as follows

#include <stdio.h>
#include <stdlib.h>
//定义全局变量
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( )
{   
	//定义局部变量
	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";
    //定义常量字符串
    char *var1 = "123456";
    char *var2 = "yushu";
    //动态分配
    int *p1=malloc(4);
    int *p2=malloc(4);
    //释放
    free(p1);
    free(p2);
    printf("栈区-变量地址\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堆区-动态申请地址\n");
    printf("                   %p\n", p1);
    printf("                   %p\n", p2);
    printf("\n全局区-全局变量和静态变量\n");
    printf("\n.bss段\n");
    printf("全局外部无初值 uninit_global_a:%p\n", &uninit_global_a);
    printf("静态外部无初值 uninits_global_b:%p\n", &uninits_global_b);
    printf("静态内部无初值 uninits_local_c:%p\n", &uninits_local_c);
    printf("\n.data段\n");
    printf("全局外部有初值 init_global_a:%p\n", &init_global_a);
    printf("静态外部有初值 inits_global_b:%p\n", &inits_global_b);
    printf("静态内部有初值 inits_local_c:%p\n", &inits_local_c);
    printf("\n文字常量区\n");
    printf("文字常量地址     :%p\n",var1);
    printf("文字常量地址     :%p\n",var2);
    printf("\n代码区\n");
    printf("程序区地址       :%p\n",&main);
    printf("函数地址         :%p\n",&output);
    return 0;
}

【2】Terminal creation and viewing

insert image description here
insert image description here

(2) STM32 verification

[1] Code generation

Since the process of automatically generating code has been done many times, I will not repeat it here. The generated code compression package is given as follows:
Link: https://pan.baidu.com/s/1jJHzOzG4AjrXWWC4wJ8xBA
Extraction code: 1521

[2] Code writing

The bsp_usart.h file
adds the header file:

#include <stdio.h>
#include <stdlib.h>

insert image description here

insert image description here
main.c file

#include "stm32f10x.h"
#include "bsp_usart.h"  //添加 bsp_usart.h 头文件

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(void)
{	
	//定义局部变量
	int a=2;
	static int inits_local_c=2, uninits_local_c;
	int init_local_d = 1;
	char *p;
	char str[10] = "lyy";
	//定义常量字符串
	char *var1 = "123456";
	char *var2 = "yushu";
	//动态分配
	int *p1=malloc(4);
	int *p2=malloc(4);
	USART_Config();//串口初始化
	output(a);
	//释放
	free(p1);
	free(p2);
	printf("栈区-变量地址\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堆区-动态申请地址\n");
	printf("                   %p\n", p1);
	printf("                   %p\n", p2);
	printf("\n全局区-全局变量和静态变量\n");
	printf("\n.bss段\n");
	printf("全局外部无初值 uninit_global_a:%p\n", &uninit_global_a);
	printf("静态外部无初值 uninits_global_b:%p\n", &uninits_global_b);
	printf("静态内部无初值 uninits_local_c:%p\n", &uninits_local_c);
	printf("\n.data段\n");
	printf("全局外部有初值 init_global_a:%p\n", &init_global_a);
	printf("静态外部有初值 inits_global_b:%p\n", &inits_global_b);
	printf("静态内部有初值 inits_local_c:%p\n", &inits_local_c);
	printf("\n文字常量区\n");
	printf("文字常量地址     :%p\n",var1);
	printf("文字常量地址     :%p\n",var2);
	printf("\n代码区\n");
	printf("程序区地址       :%p\n",&main);
	printf("函数地址         :%p\n",&output);
	return 0;
}

The bsp_usart.c file
overrides the fputc function:

int fputc(int ch, FILE *f)
{
	USART_SendData(DEBUG_USARTx, (uint8_t)ch);
	
	while(USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);
	
	return (ch);
}

insert image description here
After compiling main.c
insert image description here
, you can see the size of the Code, RO-data, RW-data, and ZI-data sections.
Note
Code: store program code
RO - data: store const constants and
instructions =Code + RO-Data + RW-Data RAM=RW-data+ZI-data


【3】Program output

Use mcuisp software to start programming.
insert image description here
After opening the serial port with SSCOM, press RESET on the chip to display the output result:
insert image description here
when using the XCOM serial port debugging assistant, it will output horizontally, and it is not recommended to use it here
insert image description here

(3) Analysis and comparison

The address value of Ubuntu in the stack area and the heap area increases from top to bottom, the address value of STM32 in the stack area decreases from top to bottom, and the address value in the heap area increases from top to bottom. From the perspective of each area, the address of the stack area is at a high address, and the address of the code area is at a low address.

3. Introduction, installation and configuration of Clion

1. Introduction to Clion

Clion is a cross-platform IDE designed for developing C and C++. It is designed on top of IntelliJ and includes many smart features to increase developer productivity. CLion helps developers use smart editors to improve code quality, automate code refactoring, and deeply integrate the CMake compilation system to improve developer productivity.

2. Install CLion2021

(1) Download

clion official website:
CLion: A Cross-Platform IDE for C and C++ by JetBrains
can be downloaded through Baidu network disk (here I borrowed someone else’s URL)
network disk: https://pan.baidu.com/s/1-uhNBBdWsPfgxBqaDqigqA
extraction Code: qwer

(2) Installation Tutorial

Double-click the exe file and click Next
insert image description here
to modify the installation location.
insert image description here
You can check it, add “bin” folder to the PATH, and you don’t need to add environment variables
insert image description here
later. Next, go to next
insert image description here
finish
insert image description here
and open clion for a short-term trial.
insert image description here
Click log in to … create an account
insert image description here
insert image description here
here I use QQ mailbox to register
insert image description here
insert image description here
and click submit. After successful registration, log out and log in again.
insert image description here
insert image description here
Click start trial
insert image description here

3. Install arm-none-eabi-gcc

(1) Download

Official website address: GNU Toolchain | GNU Arm Embedded Toolchain Downloads – Arm Developer

选择gcc-arm-none-eabi-10.3-2021.10-win32.exe

insert image description here

(2) Installation Tutorial

Select Simplified Chinese
insert image description here
and follow the installation wizard to continue.
insert image description here
insert image description here
insert image description here
insert image description here
Notepad and cmd will pop up automatically
insert image description here

4. Install openocd

(1) Download and decompress

Official website: Download OpenOCD for Windows
download is the latest 11.18, this is a compressed package, just unzip it
insert image description here
insert image description here

5. Install MinGW

(1) Download and decompress

Net disk download: https://pan.baidu.com/s/1Q9lzsIWJJ4_MPThVYDnENg
Extraction code:
After downloading qwer, just unzip the file just like openocd
insert image description here

6. Add to the system environment variable

arm-none-eabi-gcc 路径下bin文件夹
Openocd路径下bin文件夹
mingw64路径下bin文件夹

How to add system environment variables:
Settings –> System –> About –> Advanced System Settings –> Environment Variables
insert image description here
insert image description here
insert image description here
Then check whether the installation is successful
Enter arm-none-eabi-gcc -v on the command line, if there is output, it means success.
insert image description here

7. Clion configuration

(1) Create a project

insert image description here
click create
insert image description here

(2) Configure toolchains

Select File-Settings-Build-Toolchains, add MinGW, the path information will be automatically matched on the right, and select debugger arm-none-eabi-gdb.exe in the bin folder under the arm-none-eabi-gcc path
insert image description here

(3) Configure Embedded Development

Select File-Settings-Build-Embedded Development, convert the OpenOCD file directory on the right to the location you downloaded, and finally click Test and find that the prompt color is dark green, which means the configuration is successful (by the way, CubeMX is also configured)
insert image description here
OK

4. Experiment

1. Project creation

Create a new project with CLion
Select STM32CubeMX, fill in the path to save the project, and click Create
insert image description here

2. Generate project

After entering cubemx, the system defaults to f030F4Px, and we need to use f103c8t6, ​​click back to select the chip location. Then select the chip
, configure RCC , configure
insert image description here
SYS
insert image description here
, configure pins
, and set the PC13 pin as GPIO_Output to light up the LED.
insert image description here
Configure the serial port USART1
insert image description here
to name the project file and set
the Project Name to fill in again (because the process of changing the chip is actually a new ioc file created by the Cube), it is recommended to fill in the previous project name and file directory, so that you can put the previously unwanted one. ioc file is overwritten.
Then in Toolchain/IDE, select SW4STM32
insert image description here

Finally, click on the upper right corner, select Yes, generate the project, and click open projects
insert image description here

3. Configure the clion project

Back to CLion, you can see the following interface appears, select the stm32f103c8_biue_pill.cfg file, and use
insert image description here

4. Code change and burning operation

Add code
Open the main.c file and add the code to make the PC13 pin LED blink in the while loop

while (1)
  {
    /* USER CODE END WHILE */
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
    HAL_Delay(500);
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
    HAL_Delay(500);
    /* USER CODE BEGIN 3 */
  }


compile
insert image description here
burn
insert image description here

5. Results

insert image description here

V. Summary

This experiment only requires you to understand the code. You don’t need to write it yourself. You can use the code. It may be troublesome to install and configure the clion software. You need to register an account. Others need to pay attention to the operation carefully and carefully. In short, refer to the boss code and blog to complete the experiment.

6. References

https://blog.csdn.net/qq_43279579/article/details/110308101
https://blog.csdn.net/liwei16611/article/details/88545248
https://my.oschina.net/mizhinian/blog/4472814
https://blog.csdn.net/u011784994/article/details/53157614
https://blog.csdn.net/m0_58892312/article/details/121866325
https://blog.csdn.net/qq_60678931/article/details/121866156

Guess you like

Origin blog.csdn.net/m0_48609250/article/details/121961431