• MCU内存基础知识


    一、存储器分类

    在这里插入图片描述
    RAM(Random Access Memory) :掉电之后就丢失数据,读写速度块
    ROM (Read Only Memory) :掉电之后仍然可以保持数据

    单片机的RAM和ROM

    单片机的ROM,叫只读程序存储器,是FLASH存储器构成的,如U盘就是FLASH存储器。所以,FLASH和ROM是同义的。单片机的程序,就是写到FLASH中了。而RAM是随机读/写存储器,用作数据存储器,是在运行程序时,存放数据的。

    二、C语言内存分区内存区

    C语言:内存分配—栈区、堆区、全局区、常量区和代码区

    一篇带你了解C语言内存五大区——栈区,堆区,全局区,常量区,代码区

    干货——聊聊内存那些事(基于单片机系统)
    内存主要分为:代码区、常量区、静态区(全局区)、堆区、栈区这几个区域。
    在这里插入图片描述

    代码区:存放程序的代码,即CPU执行的机器指令,并且是只读的。

    常量区:存放常量(程序在运行的期间不能够被改变的量,例如: 25,字符串常量”dongxiaodong”, 数组的名字等)

    静态区(全局区):静态变量和全局变量的存储区域是一起的,一旦静态区的内存被分配, 静态区的内存直到程序全部结束之后才会被释放

    堆区:由程序员调用malloc()函数来主动申请的,需使用free()函数来释放内存,若申请了堆区内存,之后忘记释放内存,很容易造成内存泄漏

    栈区:存放函数内的局部变量,形参和函数返回值。栈区之中的数据的作用范围过了之后,系统就会回收自动管理栈区的内存(分配内存 , 回收内存),不需要开发人员来手动管理。栈区就像是一家客栈,里面有很多房间,客人来了之后自动分配房间,房间里的客人可以变动,是一种动态的数据变动。在这里插入图片描述

    1. 详细代码如下
    #include "main.h"
    #include  //用于字符串处理
    #include 	//用于printf打印
    #include  //用于分配堆区---调用malloc和free
    
    #include "delay.h"
    #include "uart3.h"
    #include "led.h"
    
    //全局区
    		int 	q1;		//未初始化全局变量
    static 	int 	q2;		//未初始化静态变量	
    const  	int   	q3;		//未初始化只读变量		
    
    		int   m1=1;		//已初始化全局变量
    static  int   m2=2;		//已初始化静态变量
    
    //常量区
    const   int   m3=3;		//已初始化只读变量
    				
    int main(void)
    {
    	SystemCoreClockUpdate(); //设置系统时钟为72M
    	LED_GPIO_Config();
    	Uart3_init();
    	
    	while(1)
    	{
    		//栈区	
    		int 	 mq1;			//未初始化局部变量
    		int  	*mq2;			//未初始化局部指针变量
    			
    		int   	mq3=3;		//已初始化局部变量	
    		char 	qq[10] = "hello"; //已初始化局部数组
    		
    		const  	int   mq4;			//未初始化局部只读变量
    		const   int   mq5=3;		//已初始化局部只读变量
    				
    		//堆区
    		int *p1 = malloc(4);    //已初始化局部指针变量p1
    		int *p2 = malloc(4);    //已初始化局部指针变量p2		
    				
    		//全局区
    		static 	int 	mp1;			//未初始化局部静态变量	
    		static  int   mp2=2;		//已初始化局部静态变量
    	
    		//常量区
    		char *vv = "I LOVE YOU";//已初始化局部指针变量
    		char *mq = "5201314";
    	
    		printf("\n栈区-变量地址\n");
    		printf("未初始化局部变量 		:0x%p\r\n",&mq1);
    		printf("未初始化局部指针变量		:0x%p\r\n",&mq2);
    		printf("已初始化局部变量			:0x%p\r\n",&mq3);
    		printf("已初始化局部数组			:0x%p\r\n", qq );
    		
    		printf("未初始化局部只读变量 		:0x%p\r\n",&mq4);
    		printf("已初始化局部只读变量		:0x%p\r\n",&mq5);
    		
    		printf("\n堆区-动态申请地址\r\n");
    		printf("已初始化局部int型指针变量p1   :0x%p\r\n", p1);
    		printf("已初始化局部int型指针变量p2   :0x%p\r\n", p2);
    
    		printf("\n全局区-变量地址\n");
    		printf("未初始化全局变量 	:0x%p\r\n",&q1);
    		printf("未初始化静态变量		:0x%p\r\n",&q2);
    		printf("未初始化只读变量		:0x%p\r\n",&q3);
    		
    		printf("已初始化全局变量 	:0x%p\r\n",&m1);
    		printf("已初始化静态变量		:0x%p\r\n",&m2);
    
    		printf("未初始化局部静态变量	 :0x%p\r\n",&mp1);
    		printf("已初始化局部静态变量	 :0x%p\r\n",&mp2);			
    		
    		printf("\n常量区地址\n");
    		printf("已初始化只读变量		  :0x%p\r\n",&m3);
    		printf("已初始化局部指针变量	  :0x%p\r\n",vv );
    		printf("已初始化局部指针变量	  :0x%p\r\n",mq );
    		
    		printf("\n代码区地址\n");
    		printf("程序代码区main函数入口地址	:0x%p\n", main);
    
    		led485_flicker();
    		delay_ms(1000);
    		
    		free(p1);
    		free(p2);        
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90

    三、STM32启动文件分析

    • STM32启动流程分析

    32位的M3有4GB的寻址空间,2^32(字节) = 4G(字节),STM32的存储器地址映射,地址范围为:0x0000_0000-0xFFFF_FFFF;其中代码区的地址是从0x0800_0000开始的,结束于0x0800_0000+芯片的Flash的大小;
    STM32寄存器版的基础知识—内存映射

    STM32单片机启动流程分析

    四、应用分析

    • STM32flash就是ROM

    1、编译器编译文件分析
    在这里插入图片描述
    在这里插入图片描述
    那么RAM是什么呢,RAM就是运行内存,掉电数据就丢失;(通常保存着堆、栈、bss段、data段、ZI-data、RW-data)

    在map文件可以查看到RAM大小
    在这里插入图片描述

    RAM = RW-data + ZI-data

    text:代码段,存储在FLASH中

    data:初始化数据 数据段

    bss:未初始化数据 数据段

    可以发现RW-data 出现在了 RAM和FLASH(ROM)中,RW-data为什么会即占用Flash又占用RAM空间?

    由前文知道RAM掉电数据会丢失,RW-data是非0初始化的数据,已初始化的数据需要被存储在掉电不会丢失的FLASH中,上电后会从FLASH搬移到RAM中
    CPU:STM32F103C8T6,LQFP64,FLASH:64KB,RAM:20KB

    flash起始地址为0x8000000,大小为0x10000(16进制)—>65536字节(10进制)—>64KB

    RAM起始地址为0x2000000,大小为0x5000(16进制)—>20480字节(10进制)—>20KB

    ROM(FLASH)的起始地址是0x8000000 512k的flash大小=512*1024=0x80000字节

    RAM的起始地址为0x20000000 大小为 64*1024=0x10000字节

  • 相关阅读:
    学习爬虫之Scrapy框架学习(1)---Scrapy框架初学习及豆瓣top250电影信息获取的实战!
    P39 事件处理
    JavsScript系列-Promise的错误捕获
    Visual Studio 中将TAB设置为空格
    网站如何优化加速,让网站降低延迟
    基于thinkphp校园二手交易网站#毕业设计
    echarts X轴类目名太长时隐藏,hover时显示全部
    文心一言 VS 讯飞星火 VS chatgpt (206)-- 算法导论15.4 3题
    【Mac】VSCode 更新1.73版本后JS&TS代码跳转异常
    校招时间紧很迷茫?校招机会怎么把握?没有项目简历怎么写?
  • 原文地址:https://blog.csdn.net/liqifff/article/details/134503113