flash代码_stm32 单片机 flash以ram的理解

背景

本篇文章将介绍一下ARM架构的ARM-M系列单片机的flash以及ram,以及程序启动的逻辑。提前申明,本人所写的本文是汲取网上的知识以及自己的理解,如果哪里讲的不对请广大网友指正。本文先以stm32f429ZIT6这个型号的单片机进行介绍。

STM32F429ZIT6微控制器2048KB FLASH,256 KB SRAM,
SDRAM 64Mbits。最高180MHz主频

FLASH

先说flash ,它在嵌入式系统中的功能可以和硬盘在PC中的功能相比。它们都是用来存储程序和数据的,好比是ROM。而且可以在掉电的情况下继续保存数据使其不会丢失。Flash memory(闪速存储器)作为一种安全、快速的存储体,具有体积小,容量大,成本低,掉电数据不丢失等一系列优点,已成为嵌入式系统中数据和程序最主要的载体。根据结构的不同可以将其分为NOR FlashNAND Flash两种。NOR Flash的特点是应用程序可以直接在闪存中运行,不需要再把代码读到系统RAM中运行。NAND Flash不行。而我们单片机基本都是NOR FLASN。而手机我们说的64 128应该是NAND FASH。

毫无疑问,stm32F429的flash是NOR Flash。

stm32F429的FLASH内部构成

  • 主存储器块,就是我们说的2MB的那个区域,也就是keil或者其他ide 将我们的程序烧写的地方。存储我们的代码以及初始化好的数据。
  • 系统存储器,存储的是一段特殊的程序,叫做bootloader,通过运行此段区域里的程序,可以对Main memory进行重新烧写。此代码是出厂的时候就固化在STM32F4里面了,专门来给主存储器下载代码的。
  • OTP区域 即一次性可编程区域,共528字节,被分成两个部分,前面512字节(32字节为1块,分成16块),可以用来存储一些用户数据(一次性的,写完一次,永远不可以擦除!!),后面16字节,用于锁定对应块。这块区域本人没用过,感兴趣的同学可以自己研究。
  • 选项字节 用于配置读写保护、 BOR 级别、软件/硬件看门狗以及器件处于待机或
    下图为stm32F429的flash构成:

v2-310d62090fc3a998af678bdc7c87aca2_b.jpg

注意,地址是从0x8000000开始的,后面会讲程序的启动与FLASH的基本关系。

stm32F429 SRAM

关于他的RAM,其实没有什么好讲的,可以把它比作电脑的内存,但是程序的运行细节和Linux是不一样的,这个后续再说。这里想强调一点是,256KB的RAM,其中64K是CCRAM
CCM 只能通过 CPU 访问,CCM是直接挂在D-bus上的,除了CPU(即Cortex-M核)之外,谁都无法访问。此外,由于CCM不属于BusMatrix的一部分,所有也就不能被其他组件访问,例如DMA控制器。对于CCM,CPU能以最大的系统时钟和最小的等待时间从CCM中读取数据或者代码。官方文档说明了使用CCM的一些优势:比如将频繁读取的数据放到CCM,将中断函数放到CCM,这都能加快程序的执行速度。另外关于CCM内存上的使用可以参考以下链接stm32F4上CCM的使用
另外三块是地址连续的RAM,大小分别是112K 16K 64K。为什么要分成三份呢?不合为一个整体呢?这个读者感兴趣可以研究下。另外ram中的地址如下图所示,
下图为MDK KEIL魔术棒的界面。

v2-860edea6f58063ad9e2e692e32708383_b.jpg

对于使用mdk keil的同学,我遇到一个坑希望读到这篇文章的同学可以避免,我在使用rt-thread下stm32f429开发版的时候,发现内存内存size数据明明写的0x30000,但是打开map文件后发现并不是,最大只是128k,少了64k,那是因为keil底下的这个√没有选择,

v2-943e93876d49601a12a1e07782fab84a_b.jpg


如果不勾选则选择已经写好的默认分散加载文件,勾选了就用魔术棒面板配置好的生成的文件。这样会导致默认使用之前配好的内存大小,这个配好的需要一个后缀名为sct的文件,即分散加载文件(即scatter file 后缀为.scf)是一个文本文件,通过编写一个分散加载文件来指定ARM连接器在生成映像文件时如何分配RO,RW,ZI等数据的存放地址。如果不用SCATTER文件指定,那么ARM连接器会按照默认的方式来生成映像文件,一般情况下我们是不需要使用分散加载文件的。具体使用可以参考以下几个链接。正常使用keil的情况无需关注,默认直接是加载到初始地址。

keil 下的分散加载文件

stm32分散加载文件

stm32单片机程序启动过程以及运行方式

启动过程

首先说一下启动模式:

v2-c1ffac3f70ee60185b1a9e0798b925b3_b.jpg

正常情况下上电会根据boot 引脚设置,以将中断向量表定位于FLASH区(一般代码都会烧写到这里),即起始地址为0x8000000,同时复位后PC指针位于0x8000000处;然后进入以startup_XXX.s 为结尾的后缀的汇编文件中,这个启动文件主要作用就是:

  1. 初始化堆栈指针SP;
  2. 初始化程序计数器指针PC;
  3. 设置堆、栈的大小
  4. 设置异常向量表的入口地址
  5. 设置C库的分支入口__main(最终用来调用main函数)
    经过上述过程然后会进入main函数里面。
    这里细节不在详细叙述,感兴趣的同学可以参考以下链接自己研究:

说一说stm32启动过程

STM32第二章-启动过程详解

程序运行

这里对于使用mdk keil的同学,我再简单说一下map文件,每次我们编译一个工程,都会生成map文件,并且在keil 中build out的窗口也会显示编译的信息,如下图:

v2-2ae343b9ee72e26798a78712bd35cd1c_b.jpg

这里我着重介绍一下几个概念:

  • Code:指代码的大小;
  • Ro-data:指除了内联数据(inline data)之外的常量数据;
  • RW-data:指可读写(RW)、已初始化的变量数据;
  • ZI-data:指未初始化(ZI)的变量数据;

Code、Ro-data:位于FLASH中;RW-data、ZI-data:位于RAM中;RW-data已初始化的数据会存储在Flash中,上电会从FLASH搬移至RAM中。

RO Size = Code + RO Data
RW Size = RW Data + ZI DataROM Size = Code + RO Data + RW Data
关于map文件可以参考下面链接

keil 里面的map文件分析
根据上面的概念,所以默认从flash启动,然后将rw-data搬运到ram,然后CPU执行代码还是在flash一条一条读取,只不过RW数据是在RAM。所以程序就是在flash里执行,也就是上文提到的NOR Flash。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值