ARM Cortex-M底层技术(1)—单片机的内存RAM和FLASH的理解

1. 存储器理解

       存储器是计算机结构的重要组成部分,存储器是用来存储程序代码和数据的部件,有了存储器计算机才具有记忆功能。按照存储介质的特性,可以分“易失性存储器”和“非易失性存储器”两类,易失和非易失是指存储器断电后,里面存储的内容是否会丢失,另一边的速度而言呢,易失性存储器的速度要快于非易失性存储器。

1.1 易失性存储器

        按照RAM的物理存储机制,可以分为DRAM(Dynamic)和SRAM(Static)两类。首先,说一下目前所用的DRAM,其通讯时序是利用时钟进行同步通讯,所以起名为Synchronous DRAM,那么,后期为了进一步提高SDRAM的通讯速度,人们设计了DDR SDRAM存储器(Double Data Rate SDRAM),随后又发展出二、三、四代SDRAM,现在很多PC机上的内存条是DDRIII SDRAM存储器。另外,静态随机存储器SRAM的存储单元以锁存器来存储数据,结构比DRAM要复杂很多,所以生产相同容量的存储器,DRAM的成本要更低,且集成度更高。

特性

DRAM

SRAM

速度

较慢

较快

集成度

较高

较低

成本

较低

较高

备注:RAM的具体存储机制和SDRAM的设计,可以看一下维基/百度百科。

1.2 非易失性存储器

        半导体类的非易失性存储器有ROM和FLASH,感觉现在ROM使用的比较少了,貌似很多都被flash代替了。之前学单片机的时候,用的外接EEPROM算是一种ROM,不作过多介绍。FLASH的容量一般比EEPROM大得多,且在擦除时,一般以多个字节为单位。如有的FLASH存储器以4096个字节为扇区或者页(page)有的flash是以512个字节为扇区或者页,最小的擦除单位为一个扇区/页至于叫做扇区还是叫做页看你使用的flash的手册。根据存储单元电路的不同,FLASH存储器又分为NOR FLASH和NAND FLASH。

特性

NOR FLASH

NAND FLASH

同容量存储器成本

较贵

较便宜

集成度

较低

较高

介质类型

随机存储

连续存储

地址线和数据线

独立分开

共用

擦除单元

以“扇区/页”擦除

以“扇区/页”擦除

读写单元

可以基于字节读写

必须以“块”为单位读写

读取速度

较高

较低

写入速度

较低

较高

NOR与NAND的共性是在数据写入前都需要有擦除操作,而擦除操作一般是以“扇区/页”为单位,而NORNAND特性的差别,主要是其内部“地址/数据线”是否分开导致的。

  • 由于NOR的地址线和数据线分开,它可以按“字节”读写数据,符合CPU的指令译码执行要求,所以假如NOR上存储了代码指令,CPU给NOR一个地址,NOR就能向CPU返回一个数据让CPU执行,中间不需要额外的处理操作。所以,在功能上可以认为NOR是一种断电后数据不丢失的RAM,但它的擦除单位与RAM有区别,且读写速度比RAM要慢得多。
  • 由于NAND的数据和地址线共用,只能按“块”来读写数据,假如NAND上存储了代码指令,CPU给NAND地址后,它无法直接返回该地址的数据,所以不符合指令译码要求。若代码存储在NAND上,可以把它先加载到RAM存储器上,再由CPU执行

综上所示,基于成本和速度的因素,目前的单片机系统内,通常采样Flash存储数据,Ram中执行数据。

1.3 Nordic的存储器

        如下图所示NRF52832使用的存储器RAM是64KB,Flash为512KB,这里的RAM是SRAM(P24 Figure5),而我认为Flash是Nor Flash(为什么如此认为呢?是因为,我可以以字节为单位去读写内部flash,擦的时候还是以页为单位)。

1.3.1 内存映射

        阐述完FLASH和SRAM的物理模型,那程序是怎么在这些存储器中运行的呢?Flash,SRAM寄存器和输入输出端口被组织在同一个4GB的线性地址空间内,可访问的存储器空间被分成8个主要块,每个块为512MB。存储器本身不具有地址信息,它的地址是由芯片厂商或用户分配,给存储器分配地址的过程就称为存储器映射,如果给存储器再分配一个地址就叫存储器重映射。NRF52832的内存映射如下图所示,

从图上可以看到,尽管给我们分配了这个大的地址空间,有很多我们用不完,所以芯片厂商只用了其中的一部分而已,我们最关心的有三个块,Block0用来设计成内部FLASH,Block1用来设计成内部RAM,Block2用来设计成片上的外设。

         在nordic芯片中FLASH存储编译后下载的程序,SRAM是存储在程序运行中的临时创建数据(ARMv7,哈弗结构),故只要你不外扩存储器,写完的程序中只要在芯片上运行起来,所有数据也就会出现在这两个存储器中。我在想那在Flsah或者Ram内部是不是又会根据不同的功能把他们分为多个模块呢?答案是肯定的。

程序文件是编译链接后生成的可执行文件,比如.bin文件,会进行分区,如下图所示,

 

  1. CODE:代码区,指程序中代码即函数体的大小,注意程序中未使用的函数也会算在CODE中,也即会占用FLASH空间,因此不用的函数最好删除掉,以免占用过多FLASH空间;
  2. RO-DATA:RO就是只读的意思,程序中只读的变量(也就是带Const的)和已初始化的字符串等;
  3. RW-DATA:特指已初始化的可读可写全局/静态变量;
  4. ZI-DATA:未初始化的可读可写全局/静态变量,注意初始化为0也算做未初始化,堆和栈也会被算入这里面;(如果你不相信栈区属于ZI-DATA,可以做一个实验,很简单,在启动文件中,将栈区大小size增加10个字节,其他代码都不动,然后编译一下,会发现ZI-DATA也增加了10个字节

        BIN文件大小 = CODE+RO-DATA+RW-DATA = 程序大小 = 程序占用的FLASH空间,为什么ZI-DATA不算?因为对于未初始化的变量BIN文件里面只需要两句话描述一下就可以了,大概就是记录下ZI-DATA的大小就好,程序运行时直接在RAM中开辟一个相应大小的空间。这里,不禁要问编译后的局部变量存放在什么区?上面局部变量属于栈空间,处理局部变量的方式和zi-data是一样的,在调用的函数中描述一下就好了。

        RW-DATA+ZI-DATA = 程序所有变量的大小 (包括全局变量和局部变量,如果还不理解,可以看分散加载文件.sct文件)

在网上看到一张图,感觉很有意思。这张图是STM32程序下载到Flash上的存储结构。

一定要区分上电前和上电后程序的不同状态(rw-data上电前会存在flash,上电后会搬运到sram)。

参考网址:https://www.cnblogs.com/amanlikethis/p/3719529.html

其中,ZI-DATA对应了BSS段(未初始化数据段),RW-DATA对应数据段(初始化数据段),CODE对应代码段,RO-DATA对应数据段(通过观察.map文件对这段话有些质疑,没搞清楚,待核实)。

 

      了解了以上基本知识,接下来就是要搞清楚程序上电是怎么启动运行的,或者说启动文件进行了什么操作、作用。

  • 21
    点赞
  • 97
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值