为什么STM32设置Flash地址0x08000000而不是0x00000000?STM32的启动过程

news/2023/5/28 8:59:11

STM32F103ZE芯片存储空间的地址映射关系图。

在这里插入图片描述

在MDK编译程序设置ROM和RAM地址时候发现:
  在这里插入图片描述
在这里插入图片描述
IROM1为片上程序存储器,即片上集成的Flash存储器,对该处理器Flash大小为512KB,即0x80000 地址区间为0x8000000~0x0807FFFF
 IRAM1为片上数据存储器,即片上集成的SRAM存储器,对该处理器RAM大小为64KB,即0x10000 地址区间为0x20000000~0x20010000
 
  这里问题为什么程序启动地址在MDK设置里为0x08000000?
  分析根据图1(Cortex-M3 预定义的存储器映射)这个是Cortex-M3核地址的映射分布图,我们看到代码区是0x00000000-0x1FFFFFFF总共对应地址大小为512MB。而对于STM32F103ZE芯片使用到的ROM空间只有512KB。Cortex-M3定下的规矩是从0地址启动,SMT32当然不能破坏ARM定下的“规矩”,所以它做了一个地址重映射的过程。
 疑问:明明代码是下载到 0x80000000 往后的存储空间中,为什么说运行又是从 0x00000000地址运行的呢?为什么不是供 0x80000000 开始运行的呢?
 有关这个问题,就是我们说的单片机的自举。
在这里插入图片描述
正常情况下都是映射到主FLASH上,所以都是从主FLASH上启动的,为了从FLASH启动,我们需要将代码下载到主FLASH上。

什么是重映射?

引用文章,如有侵权请联系作者删除
https://blog.51cto.com/u_14114084/4930970

如果0x00000000-0x001 F FFFF之前是映射在系统存储器或者嵌入式SRAM上的,现在改变BOOT0、BOOT1的电平为0、X。0x00000000-0x001 FFFFF就被重新映射在了主FLASH上,这就是单片机的地址重映射。

重映射就是本来是和张三进行映射的的,现在改为了和李四映射。换句话说重映射就是0x00000000-0x001FFFFF(1MB)本来映射在系统存储器0x1FFF0000-0x1FFF7A0F(30KB)上面,现在映射到了主FLASH0x08000000-0x081 F FFFF(1M8)上面.
在这里插入图片描述
选择从主FLASH启动时,显然FLASH会被映射在了两片地址上。

  • 原本映射的地址(1MB):0x08000000-0x081 F FFFF,进行ST-LINK下载时使用这个地址
    ·重映射的地址(1MB):0x00000000-0x001 F FFFF,启动时CPU就是从重映射的地址读取指令
  • 这两片地址都是有效的,重映射到FLASH上后,CPU从O地址开始运行时,就从FLASH上读
    取指令,当然前提是我们需要将代码下载FLASH中。
    在这里插入图片描述这就解释了为什么我们在keil中设置好程序的下载地址为0x800 0000,但是单片机上电是确实从0开始执行。是因为我们在硬件上设置了BOOT0=1,BOOT1=X,从而导致了主FLASH区(也叫主闪存,大小1MB)被映射到了0x0000 0000 - 0x001F FFFF(1MB),故而代码是下载到 0x80000000 往后的存储空间中,却说运行又是从 0x00000000地址运行的。

疑问:下载时,能不能使用 0x0000 0000 地址来下载?

答:这个不行,因为下载时,0x0000 0000 - 0x001F FFFF 还没有被重映射到 flash 上,只能使用 0x0800 0000 来下载。

既然设置到0x0800 0000这么麻烦,为什么不直接使用0x0000 0000?
这是因为STM32不仅可以从内部Flash启动,还可以从系统存储器(可以实现串口ISP,USB DFU等程序下载方式,这个程序是ST固化好的程序代码)和从内部SRAM启动,
我们将内部Flash安排到0x0000 0000显然是不行的。这样会导致系统存储器或者内部SRAM无法重映射到0x0000 0000了。
在这里插入图片描述
上面说的是我们用JLink下载器下载代码,但是有时候我们还听说可以用串口来下载程序,这又是怎么回事?

用串口下载程序,也就是我们说的ISP在系统中编程。从系统存储器启动,即STM32的ISP了。此时硬件电路B00T0=1,B00T1=0。由于串口不能直接把程序下载到主FLASH里面,所以需要使用到ST公司内嵌于系统存储区的Bootloader来引导把程序下载到主FLASH里面。JLink能直接把程序下载到内置的FLASH里面,是因为JLink下载器内部有Bootloader来引导把程序下载到FLASH里面。 程序下载完成后还需要配置BOOT引脚为BOOT0=0,BOOT1=X(即从主闪存存储器启动),复位后才能正常启动程序。如果你不修改BOOT引脚的话也就是B00T0=1,B00T1=0,那么0x0000 0000 - 0x001F FFFF是不是被重映射到系统存储器上面,而程序代码在主FLASH里面。你复位后程序肯定不能正常运行,只有在使用串口下载程序后配置BOOT引脚为BOOT0=0,BOOT1=X,复位后才能正常执行代码。你明白了吗?

总结:使用JLink下载代码,JLink下载器内部的Bootloader将程序引导下载到主FLASH里面。使用串口下载代码,由于串口没有Bootloader,就要使用ST官方内置在芯片系统存储区的Bootloader代码,将程序引导下载止主FLASH。又因为程序是从0开始执行的,所以我们复位后运行程序时一定要让BOOT0=0,BOOT1=X,将0x00000000 - 0x001FFFFF是重映射到主FLASH我们代码存在的地方,从0开始执行代码。

下图是使用FlyMcu串口下载程序,这个串口是USB-TTL,下载程序时让BOOT0=0,BOOT1=X即可。不是说在系统中编程需要将B00T0=1,B00T1=0吗?这是因为我们使用的是这个软件,这个软件可以通过DTR和RTS改变BOOT的引脚电平,达到不用修改BOOT引脚就可以下载运行代码,实际上是软件替我们做了改变BOOT引脚的操作,具体介绍可以看上面的说明。
在这里插入图片描述

ARM芯片的地址重映射 映射就是一一对应的意思。重映射就是重新分配这种一一对应的关系
  普通的单片机把可执行代码和数据存放到存储器中。单片机中的CPU从储器中取指令代码和数据。其中存储器中每个物理存储单元与其地址是一一对应而且是不可变的。如下图,CPU读取0x00000000地址上存储单元的过程
  在这里插入图片描述

ARM芯片中有些物理存储单元的地址可以根据设置变换。就是说一个物理存储单元现在对应一个地址,经过设置以后,这个存储单元就对应了另外一个地址了(重映射就是重新分配这种一一对应的关系)
  如下图
  在这里插入图片描述

上图表示把0x00000000地址上的存储单元映射到新的地址0x08000000上。CPU存取0x08000000就是存取0x00000000上的物理存储单元。网上说这种重映射设计主要是为了提高应用程序异常响应得速度。因为RAM的存取速度远高于对FLASH的存取速度,当程序发生异常后,这时代码区存在两个异常向量区,提高异常响应速度(待考证)
  那么我们看芯片上的BOOT0和BOOT1配置启动方式如下图:
  在这里插入图片描述

当BOOT1=X,BOOT0=0时(这种情况是嵌入式开发过程中产品最常用的启动方式),则CPU可以访问0x0000000或0x08000000(这两个地址是共同的物理空间)。
  验证设置ROM起始地址为0x00000000是否和0x08000000这样:

在这里插入图片描述   
  通过配置编译环境,仿真时看到memory,0x00000000和0x08000000的数据完全一致。
  如果设置ROM地址为0x0000000进行编译
在这里插入图片描述在这里插入图片描述在这里插入图片描述

通过配置编译环境,仿真时看到memory,0x00000500和0x08000500的数据完全一致。

STM32三种启动模式

下好程序后,重启芯片时,SYSCLK的第4个上升沿,BOOT引脚的值将被锁存,这就是所谓的启动过程。

STM32上电或者复位后,代码区始终从0x00000000开始,其实就是将存储空间的地址映射到0x00000000中。三种启动模式如下:

  • 从主闪存存储器启动,将主Flash地址0x08000000映射到0x00000000,这样代码启动之后就相当于从0x08000000开始。主闪存存储器是STM32内置的Flash,作为芯片内置的Flash,是正常的工作模式。一般我们使用JTAG或者SWD模式下载程序时,就是下载到这个里面,重启后也直接从这启动程序。
  • 从系统存储器启动。首先控制BOOT0、BOOT1管脚,复位后,STM32与上述两种方式类似,从系统存储器地址0x1FFF F000开始执行代码。系统存储器是芯片内部一块特定的区域,芯片出厂时在这个区域预置了一段Bootloader,就是通常说的ISP程序。这个区域的内容在芯片出厂后没有人能够修改或擦除,即它是一个ROM区。启动的程序功能由厂家设置。系统存储器存储的其实就是STM32自带的bootloader代码。
  • 从内置SRAM启动,将SRAM地址0x20000000映射到0x00000000,这样代码启动之后就相当于从0x20000000开始。内置SRAM,也就是STM32的内存,既然是SRAM,自然也就没有程序存储的能力了,这个模式一般用于程序调试。假如我只修改了代码中一个小小的地方,然后就需要重新擦除整个Flash,比较的费时,可以考虑从这个模式启动代码,用于快速的程序调试,等程序调试完成后,在将程序下载到SRAM中。
    用户可以通过设置BOOT1和BOOT0引脚的状态,来选择在复位后的启动模式。STM32三种启动模式对应的存储介质均是芯片内置的,如下图:

串口下载程序原理

从系统存储器启动,这种模式启动的程序功能是由厂家设置的。一般来说,这种启动方式用的比较少。系统存储器是芯片内部一块特定的区域,STM32在出厂时,由ST在这个区域内部预置了一段BootLoader,也就是我们常说的ISP程序,这是一块ROM,出厂后无法修改。

一般来说,我们选用这种启动模式时,是为了从串口下载程序,因为在厂家提供的BootLoader中,提供了串口下载程序的固件,可以通过这个BootLoader将程序下载到系统的Flash中。

这个下载方式需要以下步骤:

将BOOT0设置为1,BOOT1设置为0,然后按下复位键,这样才能从系统存储器启动BootLoader;
在BootLoader的帮助下,通过串口下载程序到Flash中;
程序下载完成后,又有需要将BOOT0设置为GND,手动复位,这样,STM32才可以从Flash中启动。

从汇编代码分析STM32启动过程

STM32的启动文件与编译器有关,不同编译器,它的启动文件不同。虽然启动文件(汇编)代码各有不同,但它们原理类似,都属于汇编程序。拿基于MDK-ARM的启动文件来举例,说一下要点内容。在基于MDK的启动文件开始,有一段汇编代码是分配堆栈大小的。

这里重点知道堆栈数值大小就行。还有一段AREA(区域),表示分配一段堆栈数据段。可以使用STM32CubeMX对上面的数值大小进行配置:

在IAR中,是通过工程配置堆栈大小:

看下面的汇编代码,程序上电之后,是跳到Reset_Handler这个位置。

知道代码是从Reset_Handler开始执行,再来看如下Reset_Handler汇编代码。在启动的时候,执行了SystemInit这个函数。

执行完SystemInit函数,初始化了系统时钟,之后跳转到__main函数执行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.exyb.cn/news/show-4566862.html

如若内容造成侵权/违法违规/事实不符,请联系郑州代理记账网进行投诉反馈,一经查实,立即删除!

相关文章

股票中MACD如何计算,有什么意义

MACD称为指数平滑移动平均线,是从双指数移动平均线发展而来的,由快的指数移动平均线(EMA12)减去慢的指数移动平均线(EMA26)得到快线DIF,再用2(快线DIF-DIF的9日加权移动均线DEA&…

一个使用laravel创建word的实例

这是一个从零开始使用laravel例子.一个很简单的功能,在页面上上传指标值(json格式),然后点按纽会把指标按一定格式输出word.其中使用了laravel的一些基本的功能。 1)首先创建项目CreateWord 命令行输入:laravel new CreateWord 这时会自动创建一个目录Cr…

idea 改写 插入_如何在Word 2013中控制插入/改写模式

idea 改写 插入Word has two different modes used for editing text – Insert mode and Overtype mode. Insert mode is the default and more commonly used mode. In Insert mode, text you type is inserted at the insertion point. Word具有两种用于编辑文本的模式-插入…

word文档编辑问题

输入字会把后面的字删除? 最近编辑word文档时遇到这么个问题:输入字会把后面的字删除,这个问题也不是总出现,可能把文档关闭,或者新建一个文档,这个问题就不存在了。 通过查阅资料,我发现问题在…

freemark导出word

基于业务需求需要导出word文件,在此给大家分享一个 关于freemark导出word文件的代码分享 1、第一步根据业务的要求获取到一个word文件,由此文件改为导出文件模板格式,模板格式如下: 2.将该模板另存为xml文件,进而重命…

Word初学者编辑文字时注意改写和插入两种状态

本文是我讲授课程《Word 2003从入门到精通》的有关文本基础编辑部分的补充内容。Word初学者编辑文字时注意改写和插入两种状态,一般情况下文本操作时你可能注意不到这个问题。但是,如果你无意间触发了键盘上的Insert键,那么文本输入即切换到改…

可以指定列fillna吗_京东e卡可以购买指定的京东自营商品?是真的吗

听说使用京东e卡可以购买指定的京东自营商品,京东e卡是什么?京东e卡怎么使用?如果有不知道京东e卡怎么使用的小伙伴,可以看看小编带来的内容分享。京东e卡是什么?京东e卡属于京东官方推出的一种实体礼品卡,卡内余额可以在购物的时候直接用…

在京东工作是一种什么样的体验

楼主是2016年入职京东,2018年离职的!当初入职的时候想可能会在京东呆2到3年的时候,没想到提前就离开了,但还是挺感谢老东家的!也感谢当初给我机会的领导。在京东和身边的同事们相处的都愉快的,离开了心里也…

自从加入酒水捡漏群,京东自营酒水2折捡漏,我一下子屯了6个酒柜...

小编今天实在忍不住要给大家安利一个京东天猫2折买酒方法!白酒、啤酒、洋酒、红酒通通都可以!看完能帮爱喝酒的你一年省出一辆车!话不多说,直接上图!看看小编最近都撸到些什么!!!原价…

在京东工作是一种什么体验

作者:接蒜君。微信公众号:接蒜君(jiesuanjun)。互联网公司产品。 原创不易,大家看完文章后,记得顺手点赞或分享到朋友圈哦,这是对接蒜君的支持,谢谢。 1F加班 我所在的大部门,已婚已育的男的…

网络购物有风险,某东PINKO自营也有假

相信大家有不少网购的经历,有购买时尚大牌的,也有购买不知名小件的。最近几年各种电商平台的活动也如火如荼,人们的生活也略有富余,小资们也开始偶尔轻奢一下犒劳自己。那么我们关心的问题来了,正规的电商自营平台也能…

京东补货解析

众所周知, 京东平台会有部分突然上架的商品 为此一部分手快的小伙伴还可以购买得到,然后写作一个京东监控有货下单 代码如下 var nIntervId; var count 1; var goDate; function go() { console.log("^_^ 正在帮你抢购*&#xff0a…

五个关键词和时刻 — 写在 ArcBlock 诞生两周年之际

冒志鸿读完需要6分钟速读仅需2分钟ArcBlock 区块基石创始人兼 CEO 10 月 30 日,是 ArcBlock 这个品牌诞生的日子。虽然,我们在区块链方向的努力要早于这个名字。去年此时,我写了一篇题为《纪念比特币 10 周年:未来已来&#xff0…

JVM_内存模型详解

JVM 欲渡黄河冰塞川,将登太行雪满山。 Docker中跑的JVM,总是有奇奇怪怪的问题,我们先说概念,后谈GC优化以及工具的使用 为什么会有JVM write once run anywhere - 一次编译到处运行说的是Java语言的跨平台特性。 C语言就不是跨…

两位阿里大牛联合敬献,码出高效的Java学习笔记,你值得拥有

写在前面 成长并没有直线式的捷径,“不走弯路就是捷径” 这个观点未必正确。弯路是成长的必经之路,我们在成长的路上需要注意的是保证弯路的前进大方向与直线的行进方向基本一致。 南辕北辙消耗的是时间成本、精力成本、机会成本,尤其机会成…

【Java基础知识】 异常处理机制

“欲渡黄河冰塞川,将登太行雪满山。” 系统运行,风云不测,睹始知终,秋去冬来,一叶落而知秋。 1. 什么是异常? 所有使我们程序提前终止,或者没有向预想方向去执行的错误统称为异常。 2. 异常的分…

“理想”有什么理想?

近日,理想汽车发布截至2020年12月31日的2020年未经审计财务报告,报告中显示2020全年总收入为94.6亿元人民币,现金储备达到298.7亿元人民币。 据报道了解,在财报发布之前理想汽车的内部信中公布,理想汽车2025年的战略目…

缓存一致性问题怎么解决

关于Redis的其他的一些面试问题已经写过了,比如常见的缓存穿透、雪崩、击穿、热点的问题,但是还有一个比较麻烦的问题就是如何保证缓存一致性。对于缓存和数据库的操作,主要有以下两种方式。先删缓存,再更新数据库先删除缓存&…

手把手教你做智能LED灯(三) 手机控制端开发

第3节 手机控制端开发 Arduino开发板已经可以接收命令了。接下来就要开始考虑手机端如何控制LED灯。 我们在之前一篇文档中开发过蓝牙聊天应用,那里面详细介绍了蓝牙设备互相连接的原理和实现方法。在这一节中,我们只需要将那个应用稍微做些改造&#…

拯救熊猫眼!戒除手机瘾!不做手机控,全靠它了!

“想保护眼睛,却放不下手机? 番茄工作法,却坚持不了三分钟? 只想看看消息,却刷朋友圈刷到下课? 明明要早起,却躺在床上练成王者熊猫眼? 要看的书堆成山,却阻挡不住刷…