FLASH、SRAM、编译文件 相关记录
前言
文章内容参考借鉴网络论坛资料信息
参考链接:https://stackoverflow.com/questions/5430284/rom-and-ram-in-arm
https://blog.youkuaiyun.com/qq_34810707/article/details/87942328
1、ROM、RAM、SRAM和FLASH的区别
RAM可以分为静态RAM(SRAM)、动态RAM(DRAM)
静态RAM(SRAM) | 读写速度最快,价格贵 | cpu一级二级缓冲,不需要动态刷新,掉电数据丢失 |
---|---|---|
动态RAM(DRAM) | 比SRAM读写慢,比ROM快,价格比SRAM便宜 | cpu内存,电路动态刷新,否者丢失数据;常见有FPRAM/FastPage、EDORAM、SDRAM、DDR RAM、RDRAM、SGRAM以及WRAM等, |
ROM可以区分为
PROM | 可编程,一次性的,也就是软件灌入后,就无法修改了,这种是早期的产品,现在已经不可能使用了 |
---|---|
EPROM | EPROM是通过紫外光的照射擦出原先的程序,是一种通用的存储器 |
EEPROM | 通过电子擦除,价格很高,写入时间很长,写入很慢 |
flash
flash | 具备电子可擦除可编程,掉电不丢失数据,代替ROM用作系统和程序代码存储 |
---|
2、SRAM存放内容
1、各个文件中声明和定义的全局变量、静态数据和常量(没有加const修饰);
2、HEAP区;
3、STACK区。
堆区(heap):一般由程序员使用malloc或new来进行分配,在适当的时候用free或delete来进行释放。若程序员不释放,程序结束时可能由操作系统回收。分配方式类似于数据结构中的链表。
栈区(stack):由编译器自动分配和释放,程序员不做干涉。存放函数的参数值、局部变量的值等,其操作方式类似于数据结构中的栈。程序的中断,函数的形式参数传递等都需要STACK来实现。
注意:
1、堆栈的大小在编译器编译之后是不知道的,只有运行的时候才知道,所以需要注意一点,就是别造成堆栈溢出了,不然就会发生hardfault错误。
2、所有在处理的函数,包括函数嵌套,递归,等等,都是从这个“栈”里面,来分配的。所以,如果栈大小为2K,一个函数的局部变量过多,比如在函数里面定义一个u8 buf[512],这一下就占了1/4的栈大小了,再在其他函数里面来搞两下,程序崩溃是很容易的事情,这时候,一般你会进入到hardfault….这是初学者非常容易犯的一个错误.切记不要在函数里面放N多局部变量,尤其有大数组的时候!
3、 STM32的栈,是向下生长的。事实上,一般CPU的栈增长方向,都是向下的。而堆的生长方向,都是向上的。堆和栈,只是他们各自的起始地址和增长方向不同,他们没有一个固定的界限,所以一旦堆栈冲突,系统就到了崩溃的时候了。
4、程序中的常量,如果没加const也会编译到SRAM里,加了const会被编译到flash中。
3、编译文件中的Code、RO-data、RW-data、ZI-data含义
Code:即代码域,它通常是指编译器生成的机器指令,这些内容会被存储到ROM区。
RO-data:Read Only data,即只读数据域,它指程序中用到的只读数据,这些数据被存储在ROM区,因而程序不能被修改的内容。例如C语言中const关键字定义的变量就是典型的RO-data。
RW-data:Read Write data,即可读写数据域,它指初始化为“非0值”的可读写数据,程序刚运行时,这些数据具有非0的初始值,程序运行的时候它们又会常驻在RAM区,应用程序可以修改其内容。例如C语言中定义的全局变量,且定义时赋予“非0值”给该变量。
ZI-data:Zero Initialie data,即0初始化数据,它指初始化为“0值”的可读写数据域,它与RW-data的区别是程序刚运行时这些数据初始值全都为0,程序运行时和RW-data的性质一样,它们也常驻在RAM区,应用程序可以更改其内容。例如C语言中使用定义的全局变量,且定义时赋予“0值”给该变量(如若定义该变量时没有赋予初始值,编译器会把它当ZI-data来对待,初始化为0);
4、如何查看编译后的文件大小
步骤一:当你的程序编译通过没错的情况下,可以在下面看到如下信息:
步骤二:在你的工程文件里搜索.map文件,并打开他,下滑到最下面找到如下信息
FLASH中的被占用的空间为:Code+RO Data+RW Data
芯片内部RAM使用的空间为: RW Data + ZI Data
插图理解