当前位置: 首页 > news >正文

MCU内存基础知识

文章目录

  • 一、存储器分类
  • 二、C语言内存分区内存区
  • 三、STM32启动文件分析
  • 四、应用分析

一、存储器分类

在这里插入图片描述
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 <string.h> //用于字符串处理
#include <stdio.h>	//用于printf打印
#include <stdlib.h> //用于分配堆区---调用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(); //设置系统时钟为72MLED_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);    //已初始化局部指针变量p1int *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);        }
}

三、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字节

相关文章:

  • bclinux aarch64 openeuler 20.03 LTS SP1 部署 fastCFS
  • 电动汽车充放电V2G模型MATLAB代码
  • 生产问题 Recv-Q101
  • 深度学习之生成唐诗案例(Pytorch版)
  • 【LeetCode刷题】--40.组合总和II
  • 【shell脚本】全自动完成pxe无人值守批量装机脚本,匹配centos系列
  • Jetson JetPack-5.1.2-L4T-R35.4.1 修复deskew algorithm的问题
  • 基于Qt的UDP通信、TCP文件传输程序的设计与实现——QQ聊天群聊
  • Java Fasn 带您谈谈——开源、闭源
  • 利用Python进行数据分析【送书第六期:文末送书】
  • upload-labs关卡12(基于白名单的%00截断绕过)通关思路
  • Modbus转Profinet网关在大型自动化仓储项目应用案例
  • HTML玩转超链接a标签
  • linux 内存回收代码注释(未实现多代lru版本)
  • java_函数式接口
  • 【剑指offer】让抽象问题具体化
  • Android开源项目规范总结
  • create-react-app项目添加less配置
  • CSS实用技巧干货
  • java 多线程基础, 我觉得还是有必要看看的
  • Java反射-动态类加载和重新加载
  • java中具有继承关系的类及其对象初始化顺序
  • leetcode-27. Remove Element
  • Python语法速览与机器学习开发环境搭建
  • React as a UI Runtime(五、列表)
  • Vue 重置组件到初始状态
  • 阿里中间件开源组件:Sentinel 0.2.0正式发布
  • 工作手记之html2canvas使用概述
  • 机器学习学习笔记一
  • 深度学习在携程攻略社区的应用
  • 试着探索高并发下的系统架构面貌
  • 我这样减少了26.5M Java内存!
  • 移动端解决方案学习记录
  • 树莓派用上kodexplorer也能玩成私有网盘
  • ​​​​​​​GitLab 之 GitLab-Runner 安装,配置与问题汇总
  • #162 (Div. 2)
  • (1)(1.11) SiK Radio v2(一)
  • (2)关于RabbitMq 的 Topic Exchange 主题交换机
  • (8)Linux使用C语言读取proc/stat等cpu使用数据
  • (二)【Jmeter】专栏实战项目靶场drupal部署
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (附源码)springboot青少年公共卫生教育平台 毕业设计 643214
  • (附源码)计算机毕业设计SSM保险客户管理系统
  • (四)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (一)搭建springboot+vue前后端分离项目--前端vue搭建
  • (原創) 如何使用ISO C++讀寫BMP圖檔? (C/C++) (Image Processing)
  • (终章)[图像识别]13.OpenCV案例 自定义训练集分类器物体检测
  • .mat 文件的加载与创建 矩阵变图像? ∈ Matlab 使用笔记
  • .NET / MSBuild 扩展编译时什么时候用 BeforeTargets / AfterTargets 什么时候用 DependsOnTargets?
  • .NET 5.0正式发布,有什么功能特性(翻译)
  • .NET Core 2.1路线图
  • .NET core 自定义过滤器 Filter 实现webapi RestFul 统一接口数据返回格式
  • .NET Core使用NPOI导出复杂,美观的Excel详解
  • .net mvc 获取url中controller和action
  • .NET框架设计—常被忽视的C#设计技巧