其他分享
首页 > 其他分享> > 变量存储重温与Clion编辑器的学习与实践

变量存储重温与Clion编辑器的学习与实践

作者:互联网

编写一个C程序,重温全局变量、局部变量、堆、栈等概念

一、C程序的内存分配

栈区(stack)
由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
堆区(heap)
一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收 。它与数据结构中的堆不同,分配方式类似于链表。
全局区(静态区)(static)
全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量、未初始化的静态变量在相邻的另一块区域。当程序结束后,变量由系统释放 。
文字常量区
存放常量字符串。当程序结束后,常量字符串由系统释放 。
程序代码区
存放函数体的二进制代码。
正常的程序在内存中通常分为程序段、数据段、堆栈三部分。
程序段里放着程序的机器码、只读数据,这个段通常是只读,对它的写操作是非法的。
数据段放的是程序中的静态数据。
堆栈是内存中的一个连续的块。一个叫堆栈指针的寄存器(SP)指向堆栈的栈顶。堆栈的底部是一个固定地址。堆栈有一个特点就是,后进先出。也就是说,后放入的数据第一个取出。它支持两个操作,PUSH和POP。PUSH是将数据放到栈的顶端,POP是将栈顶的数据取出。动态数据存放在堆栈中。

存储区图解
在这里插入图片描述

二、Ubuntu,stm32开发板编程,输出信息进行验证

初始程序

#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 = "1234567890";
    char *var2 = "qwertyuiop";
    //动态分配
    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;
}

Ubuntu

在这里插入图片描述

STM32

创建工程的过程就不介绍了可以直接去下面链接提取
工程链接
链接:https://pan.baidu.com/s/1SWCUT1Hvw-hXiyj20IaX1A
提取码:x7ba
代码如下:

修改一下主函数(test.c)


#include "usart.h"		
#include "delay.h"	
#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(void)
{				 
	u16 t; u16 len; u16 times=0;
	Stm32_Clock_Init(9);	//??????
	delay_init(72);	  		//?????
	uart_init(72,115200); 	//??????115200
  	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[10] = "haohao";
    //定义常量字符串
    char *var1 = "1234567890";
    char *var2 = "haohaoshahaizi";
    //动态分配
    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;
	}	 
} 


点击魔法棒,勾选C99 Mode
在这里插入图片描述
在调整一下设置
在这里插入图片描述
烧录成功
在这里插入图片描述
在这里插入图片描述

安装Clion2021,采用一套新的嵌入式软件开发工具包(替代Keil),完成stm32F103 点亮LED的程序。

一、CLion

介绍

Clion 是一款专门开发 C 以及 C++ 所设计的跨平台的 IDE。它是以 IntelliJ 为基础设计的,包含了许多智能功能来提高开发人员的生产力。
这种强大的 IDE 帮助开发人员在 Linux、OSX 和 Windows 上来开发 C/C++ ,同时它还能使用智能编辑器来提高代码质量、自动代码重构并且深度整合 Cmake 编译系统,从而提高开发人员的工作效率。
CLion 支持 GCC、clang、MinGW、Cygwin 编译器以及 GDB 调试器。提供对 Cmake 支持:包含自动处理 Cmake changes 和 Cmake Targets,更新新创建的 C/C++ 档案以及 Cmake Cache 编辑器。

下载

官网下载:CLion2021.2 Winx64
https://www.jetbrains.com/zh-cn/clion/download/#section=windows
安装过程忘记截图了可以去https://blog.csdn.net/m0_58892312/article/details/121866325看一下安装过程
在这里插入图片描述

安装配置 arm-none-eabi-gcc

windows 上到这下载:
GNU Toolchain | GNU-RM Downloads – Arm
https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads
进入网页后,点击 gcc-arm-none-eabi-10.3-2021.10-win32.zip 下载
在这里插入图片描述
安装好以后,将安装目录下的 bin 文件夹添加到环境变量
测试是否安装成功
在命令行里用以下语句测试:arm-none-eabi-gcc -v
如下图,有信息输出,那就是装好了
在这里插入图片描述

三、安装配置 MinGW

打开网址:
https://sourceforge.net/projects/mingw-w64/files/Toolchains targetting Win64/Personal Builds/mingw-builds/
下载 MinGW 官方压缩包
不要点击绿色的按钮,一直向下滑动,找到压缩包,点击下载既可
在这里插入图片描述
解压成功后
在这里插入图片描述

开始操作

进入 CLion,新建一个工程
在这里插入图片描述
选择一个存放地点
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

下载OpenOCD

去https://gnutoolchains.com/arm-eabi/openocd/处下载
在这里插入图片描述
在这里插入图片描述
选择 File-Settings-Build-Embedded Development,将右侧的 OpenOCD 文件目录转换到自己下载的位置,最后点击 Test 发现提示颜色为墨绿色,即代表配置成功 (顺便把 CubeMX 也配置了)
在这里插入图片描述

利用 CLion 点亮 LED

用 CLion 创建新工程
选择 STM32CubeMX ,填写好项目要保存的路径,点击 Create 即可
在这里插入图片描述
等待调用 STM32CubeMX
在这里插入图片描述
工程创建好后,点击 Open with STM32CubeMX,进入 CubeMX
在这里插入图片描述
打开之后,点击左上角的如图位置,进入芯片选择
在这里插入图片描述
选择使用 STM32F103C8,之后点击 Start Porject 开始配置
在这里插入图片描述
配置 SYS
在这里插入图片描述
配置 RCC
在这里插入图片描述
配置引脚
设置 PC13 引脚为 GPIO_Output 来点亮 LED 灯。
在这里插入图片描述
配置串口 USART1
在这里插入图片描述
命名工程文件并设置
Project Name 要重新填写一下(因为换芯片的过程,其实是 Cube 新建了一个 ioc 文件),建议填写之前的工程名和文件目录,这样就可以把之前不想要的那个 .ioc 文件覆盖掉。
然后" Toolchain/IDE "那里,选择 SW4STM32
在这里插入图片描述
回到 CLion,可以看到出现了如下界面,选择 st_nucleo_f103rb.cfg 文件,并使用
注意:如果回到 CLion之后没有出现如下界面,那就可能是你上一步生成 CubeMX 工程的时候,文件命名和目录选择与之前的不同导致的,只需要重新在 CLion 打开你重新生成的 CubeMX 工程文件目录即可。
在这里插入图片描述
寻找 st_nucleo_f103rb.cfg 文件位置
点击左上角如图位置
在这里插入图片描述
出现下面界面,点击图中的 …
在这里插入图片描述
修改 st_nucleo_f103rb.cfg 文件
根据刚才查看到的目录位置打开该文件,将第十行注释掉
在这里插入图片描述
添加代码
打开 main.c 文件,在 while 循环里添加使 PC13 引脚 LED 闪烁的代码

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 */
  }

在这里插入图片描述
编译以后烧录
在这里插入图片描述

参考

https://blog.csdn.net/m0_58892312/article/details/121866325
https://blog.csdn.net/qq_43279579/article/details/110308101

标签:int,local,global,重温,init,编辑器,inits,printf,Clion
来源: https://blog.csdn.net/qq_52772319/article/details/121958762