一般来说单片机的内存指的是FLASH和RAM,当在程序中定义了全局变量、局部变量、只读变量等参数时都是会存放到对应的FLASH或者是RAM中。具体对单片机FLASH和RAM的介绍之后再写,这里只对单片机内存分配,对堆和栈以及变量的存储做一个梳理和记录。
1、FLASH(0x0800 0000)
FLASH主要是存放程序代码、全局变量(不为零)及常量的。下面是将 FLASH内部进行细分之后的一张图。
STM32的FLASH是从地址0x0800 0000开始的,是向上增长的。FLASH又可以细分为这么几个部分:
(1)文本段 (Text),其中文本段中又包含可执行代码 (Executable Code)和常量 (Literal Value);例如:const int B=1中的B的地址以及我们自己写的程序代码的地址均储存在FLASH的文本段中;
(2)只读数据区域 (Read Only Data);
(3)数据复制段 (Copy of Data Section),这个段充当的作用是存放程序中初始化为非0值的全局变量的初始值,之所以要将初始值存放到这里,是因为全局变量是存放在RAM上的,RAM上的值掉电便丢失,每次上电后这些变量是要进行重新赋值的,而重新赋的值就存放在这里;
这是一个特别的情况,就是初始值不为零的全局变量,他储存的地址是在FlASH中,但开始运行程序时,这个定义的全局变量就会被拷贝到RAM中,此时若要查询变量的地址,发现是在RAM中;可通过查看ST-LINK Utility查看全局变量的地址。
2、RAM(0x2000 0000起)
相对与FLASH来说,RAM主要就是用来存储数据了,在RAM中值得关注的是堆和栈的空间,堆是向上增长的而栈是向下生长的,如果一个函数运行的时候有大量的局部变量(栈向下增长),同时程序在整个过程中malloc申请了大量的堆空间而没有释放(堆向上增长),造成堆和栈空间的冲突,一旦堆栈冲突,系统就崩溃了。
如下是STM32中RAM的分区:
RAM中包含了如下几个部分:
(1)data:存放初始化为非0值的全局变量;
(2)bss:存放未初始化或者是初始化为0的全局变量;
(3)堆(Heap) : 由malloc申请,由free释放;堆是程序在运行的时候用malloc或new申请任意大小的内存,程序员自己负责在适当的时候用free或delete释放内存。可以根据需要请求一段连续的内存空间,并在程序执行过程中随着数据的变化而增长或减小。
(4)栈(Stack) : 存放局部变量、函数调用时的返回地址以及中断入口等;函数执行结束时这些存储单元自动被释放,其大小主要看函数调用的深度。
这是一个特殊的内存区域,主要用于存储程序执行过程中的局部变量、函数参数和函数调用的返回地址。它是按照后进先出的原则工作的,类似于生活中的堆叠物品。
堆和栈的空间可以由我们来自由设定,可在在STM32的启动文件(.s)中,刚开头就有对堆(Head_Size)和栈(Stack_Size)空间的定义描述。堆栈是一种用于存储函数调用和局部变量的内存区域。在STM32中,堆栈通常位于SRAM中的特定区域。