[Skill] STM32的启动方式、启动文件、程序下载方式和下载电路——深度解读(全网最全最详细)

目录

前言

一、STM32的存储器类型

1.1 存储器组织结构

1.2  嵌入式Flash(闪存)

Flash架构

Flash结构

1.3  嵌入式SRAM

系统SRAM架构

系统SRAM结构 

二、STM32的启动

2.1 启动流程

2.2  STM32启动硬件配置——BOOT【1:0】引脚

 BOOT[1:0]引脚配置描述        

 启动方式

2.3  STM32启动软件配置——启动文件

启动文件名称

启动文件内容

2.4  STM32启动举例详细介绍

三、三种启动方式

3.1 ISP

简介

STM32中的ISP下载方式

3.2 ICP

简介

STM32中的ICP下载方式

3.3 IAP

简介

STM32中的ICP下载方式

四、三种硬件电路

4.1 串口ISP电路

 4.2 JTAG下载调试电路

 4.3 SWD下载调试电路

五、参考资料


前言

为了大家更好的理解STM32的启动方式,这里将以上资料进行整合并从以一下几点进行详细介绍:

一、STM32的存储器类型

二、STM32的启动

三、三种下载方式

四、三种硬件电路

一、STM32的存储器类型

1.1 存储器组织结构

程序存储器、数据存储器、寄存器、I/O端口排列在同一顺序的4GB地址空间内。

可寻址的存储空间分为8个主要块,每个块为512MB;未分配给片上存储器和外设的所有存储区域视为“保留区”。

请参考数据手册中的存储器映射图。

每次芯片复位后,所有外设时钟都被关闭(SRAM和Flash接口除外)。使用外设前,必须在 RCC_AHBxENR 或 RCC_APBxENR 寄存器中使能其时钟。

1.2  嵌入式Flash(闪存)

Flash架构

Flash接口可管理CPU通过AHB I-Code和D-Code对Flash进行访问。该接口可针对Flash执行擦除和编程操作,并实施读写保护机制。

Flash接口通过哦指令和缓存机制加速代码执行。

由于本人使用的STM32F407系列开发板,因此将其作为参考讲解:

 Flash接口具体系统架构:

Flash结构

  • 主存储块,分为4个16KB扇区、1个64KB扇区和7个128KB扇区,起始地址:0x0800 0000
  • 系统存储器期间在系统存储器启动模式下从该存储器启动,起始地址:0x1FFF 0000
  •  512字节OTP(一次性可编程),用于存储用户数据。OTP区域还有16个额外字节,用于锁定对应的OTP数据块
  • 选项字节,用于配置读写保护、BOR级别、软/硬件看门狗以及器件处于待机或停止模式下复位。

1.3  嵌入式SRAM

STM32F405xx/07xx STM32F415xx/17xx 带有 4 KB 备份 SRAM和 192 KB 系统 SRAM

系统SRAM架构

系统SRAM结构 

可按照字节、半字(16位)或全字(32位)访问,执行速度cpu速度,且等待周期为0。

  • 映射在地址0x2000 0000的112KB和16KB的SRAM,可供所有AHB主控总线访问。
  • 映射在地址0x2002 0000的64KN,可供所有AHB主控总线访问。
  • 映射在地址0x1000 0000映射的64KB块,只能供CPU通过数据总线访问。

二、STM32的启动

在这里插入图片描述

2.1 启动流程

        在嵌入式开发过程中,由于是使用C编程,很少涉及到机器底层寄存器的执行,一般都会从main函数里开始写代码,也都知道代码运行是从main函数开始执行。在C语言代码执行过程中通常是机器先读取下一条语句的地址,然后从程序存储器中读取该地址的程序,然后再执行这条语句。那么问题来了,下一条语句的地址可以根据本条语句的地址来寻找到,但是main函数最开始的程序的入口地址如何找到?

        事实上微控制器是无法从硬件上去定位main函数的入口地址,因为使用C语言作为开发语言后,变量/函数的地址便由编译器在编译时自行分配,因此main函数的入口地址在编译后并不是固定不变的,因此需要通过一个启动文件来寻找到main的入口地址。

        以前接触无论是PIC、AVR、MSP430或51过程中都会有涉及到启动文件的配置,仅仅只有熔丝位或配置字是需要根据实际使用配置来设置,其实并非没有,而是大部分开发环境往往自动完整提供了这个启动文件,不需要开发人员对其进行配置和干预,只需要从main函数开始程序涉及即可。但是对于嵌入式来说,当接触到嵌入式内核,在片上跑系统时却是很重言的环节。如Linux系统移植过程“bootloader”。启动文件完成微控制器从“复位”到“开始执行main函数”中间这段时间必要启动配置。

启动流程:

  1. 硬件选择启动模式

  2. 读取启动模式对应的存储器的中断向量表

  3. 初始化栈

  4. 初始化PC指针,指向Reset_Hander

  5. 初始化系统时钟

  6. 执行C库函数_main,进入C语言世界,执行main函数

        相对于ARM上一代主流ARM7/ARM9内核架构,新一代Cortex内核架构的启动方式有了很大的变化。ARM7/9内核的控制器在复位后,CPU会从存储空间的绝对地址0x0000 0000取出第一条指令执行复位中断服务程序的启动方式,即固定了复位后的起始地址为0x00000000(PC=0X00000000)同时中断向量表的位置并不是固定的。而Cortex-M内核则正好相反,其中断向量表位置是固定的,而启动地址是根据启动方式来定义

如果不能理解上面一段的内容,请参考2.4节关于STM32启动的举例,看完后回来看就会恍然大悟 

补充知识:详细可参考芯片的手册

中断向量表:本质上是一个32位整数数组,当他存储了发生异常时需要执行对应任务函数的地址,当发生异常情况时,会将对应的地址幅值给PC寄存器,进而执行任务。以下给出部分中断向量表

在这里插入图片描述 优先级:优先级标号越小优先级越高 ;MSP:Main Stack Pointer

2.2  STM32启动硬件配置——BOOT【1:0】引脚

       由于Cortex内核架构的存储器采用固定的存储器映射,代码区域起始地址为0x000 0000(通过ICode/DCode总线访问),而数据区域(SRAM)起始地址为0x2000 0000(通过系统总线访问)。

带有FPU(浮点运算单元)的Cortex-M内核的CPU始终通过ICode总线获取复位向量,这就意味着只有代码区域(通常为Flash)可以提供启动空间。STM32微控制器实现了一种特殊的机制,能够从其他存储器(如内部SRAM)启动。

可以通过BOOT[1:0]引脚选择三种不同的启动模式,如表2:

  •  BOOT[1:0]引脚配置描述        

在MCU复位后,在SYSCLK的第四个上升沿锁存BOOT引脚值。复位后,用户通过设置BOOT1和BOOT0引脚来选择启动方式。

BOOT0 为专用引脚,而 BOOT1 则与 GPIO 引脚共用。一旦完成对 BOOT1 的采样,相应GPIO 引脚即进入空闲状态,可用于其它用途。

器件退出待机模式时,还会对 BOOT 引脚重新采样。因此,当器件处于待机模式时,这些引
脚必须保持所需的启动模式配置。这样的启动延迟结束后, CPU 将从地址 0x0000 0000
取栈顶值,然后从始于 0x0000 0004 的启动存储器开始执行代码。
         注意: 如果器件从 SRAM 自举,在应用程序初始化代码中,需要使用 NVIC 异常及中断向量表和偏移寄存器来重新分配 SRAM 中的向量表。
  •  启动方式

Cortex-M3内核规定,起始地址0x0000 0000必须存放堆顶指针,而第二个地址0x0000 0004 则必须存放复位中断入口向量地址,在复位后,会从起始地址的下一个32位空间取出复位中断入口向量,跳转执行复位中断服务程序。

  • Main Flash memory(BOOT0 = 0)

        选择Flash的主存储块作为启动空间,即中断向量表定位于Flash的主存储区域,起始(中断入口)地址:0x0800 0000,同时复位后PC指针位于0x8000 0000处。常见的下载方式:JTAG或者SWD模式下载程序,就是将程序直接下载到Flash里面,复位重启后也直接从Flash启动。

开发调试中由于某些原因导致内部Flash锁死,无法链接SWD以及JTAG调试,无法读到设备,则可以通过BOOT将启动方式调整为其余两种来重新烧录程序,达到更新Flash内部代码。

  • System memory(BOOT0 = 1 ; BOOT1 = 0)

        选择系统存储器作为启动空间,即中断向量表定位于Flash的系统存储区域(STM32在出厂时,由ST在这个区域内部预设了一段BootLoader,也就是常说的ISP程序,出场后无法修改),起始(中断入口)地址:0x1FFF 0000,通常使用这种启动方式来实现串口下载程序,BootLoader负责下载程序的时候对芯片内部的Flash进行擦除于编写。在使用ISP下载完程序后需要将启动方式重新调整为Flash启动模式(即将BOOT0=0),复位后MCU才会正常运行。

  • Embedded SRAM(BOOT0 = 1 ; BOOT1 = 1)

        选择嵌入式SRAM(静态随机存储器)作为启动空间,即中断向量表定位于系统SRAM存储区域,起始(中断入口)地址:0x2000 0000,同时复位后PC指针位于0x2000 0000处。一般是编写一些小程序用来扫描所有的I/O口,然后再上测试信号,借此检测所有焊接是否正常,这样不必触动Flash中的程序。

2.3  STM32启动软件配置——启动文件

启动文件名称

STM32F10系列启动文件(由ST公司提供)

 STM32F40系列启动文件(由ST公司提供)

startup_stm32f40_41xxx.s

启动文件内容

  • 初始化堆
  • 初始化栈
  • 配置中断处理函数Reset_Handler
  • 配置系统时钟
  • 通过C/C++标准实时库的_main函数,跳转到.C文件的main函数
  • 用户堆栈配置

启动文件,首先对栈和堆(两者的区别请参考前言中的资源9)的大小进行定义,并在代码区的起始处建立中断向量,其第一个表项是栈顶地址,第二表项是复位中断服务入口地址。然后在复位中断服务程序中跳转;C/C++标准实时库的_main函数,完成用户堆栈等的初始化后,跳转.c文件中的main函数开始执行C程序。

关于启动文件更详细的解释请参考资料6、7

2.4  STM32启动举例详细介绍

敲黑板划重点的来了,只要理解了这一部分,回头看前面的知识点就不会一头雾水了。

有了之前的知识点作为铺垫,这部分将会举一个具体的例子进行详细说明。

假设:STM32板子里已经下载好了程序(已经含有了启动文件、main函数文件)、板子硬件

Boot0 = 0 ; Boot1 =x(从Flash主存储器启动,起始地址0x8000 0000)。

执行流程: 对STM32板子上电或者对其进行复位,由于MCU中存在启动文件,所以上电后已经将栈/堆的大小、中断向量表、中断服务函数Reset_Handler配置好了。复位后,在SYSCLK的第四个上升沿锁存BOOT引脚值(此时为Flash主存储器启动,起始地址0x8000 0000)。那么栈顶地址(0x0000 0000)会存放0x8000 0000(Flash起始地址,启动地址),而启动地址(0x8000 0000)会存放0x0000 0004(复位中断服务入口地址),执行复位中断服务程序(Reset_Handle函数),函数内有跳转_main函数,通过_main函数进入到main,来到C的世界。

针对2.1节的RAM7/9的启动和Cortex-M的启动做出解释:

 

ARM7/9的起始地址是固定的都是(0x0000 0000),但是中断向量表的地址却不是固定的,中断向量表中的该中断地址就是调用的地址,是变化的。

Cortex的起始地址是不固定的(根据BOOT来设置),但是起始地址也存放于0x0000 0000,在程序调用中断的时候调用的是中断的地址(中断向量表),并不会直接跳到中断函数中,在中断的地址空间中会存放该中断函数的入口地址,因此可以说起始地址是不固定的,而中断向量表是固定的。


三、三种启动方式

单片机程序下载方式由三种:

  • ISP(In System Programing,在系统编程)
  • ICP(In Circuit Programing,在电路编程)
  • IAP(In Applicating Programing,在应用编程)

3.1 ISP

简介

        MCU必须处于可执行程序状态(除了上电,还要节XTAL),且必须预烧ISP-code在LDROM里面。烧录范围只限于APROM、DataFlash或CONFIG,chip在LOCK状态,任然可以更新某一块区块(APROM、DataFlash或CONFIG),由于烧录动作取决于ISP-code,所以给系统设计者弹性较大。

STM32中的ISP下载方式

        针对STM32来说,ISP-code是BootLoader程序,LDROM就是Flash中的系统存储器,将程序烧录到Flash中的主存储器中。该下载方式一般通过串口(USB)下载程序。在下载的时候需要调以下MCU的启动方式:

  • step1:将BOOT0=1,BOOT1=0,然后按下复位键,STM32将会从Flash的系统存储器启动
  • step2:在系统存储器中的BootLoader程序帮助下,将工程的.HEX文件,通过串口助手(FlyMcu)下载到32的Flash中主存储器
  • step3:将BOOT0=0,BOOT1=X,然后按下复位键,STM32将会从Flash的主存储器启动

3.2 ICP

简介

        MCU只要处于上电状态,不必预烧任何code在MCU里面。烧录覆盖到整个MCU芯片,chip在LOCK状态下,无法更新某一块区块,只能在erase-ALL之后,更新某一区块,再逐一烧回其他区块(因为ICP的本质就是走串行借楼的Writer Mode,chip被LCOK后,除了erase-ALL,所有烧录动作皆会被进制)。因为烧录纯粹是ICP硬件的行为,MCU无法自己更新自己所以给系统设计者弹性较小。

STM32中的ICP下载方式

        针对STM32来说,启动方式是Flash的主存储器启动(BOOT0=0,BOOT1=X),这种下载方式一般通过JTAG、SWD(几条线)来下载,而上述简介则描述的是Flash被锁死无法下载的情况。

3.3 IAP

简介

        MCU在运行的状态下,利用利用ISP的机制,不透过外接工具的帮忙,去更新APROM、DataFlash或CONFIG。

STM32中的ICP下载方式

        ICP是直接将程序下载到Flash中,ISP则是 通过了BootLoader程序下载到Flash中,对于BootLoader程序用户是不可以更改的,那难道用户不可以自己定义这种文件么?当然可以,对于IAP下载方式,可以将Flash主存储器分为两部分,第一部分是类似BootLoader的功能的程序,可以使用其他通讯接口和方式来实现(TTL、RS232、RS485、I2C、SPI、CAN等等),而第二部分才是真正的程序代码。这种方式需要预先在Flash中设置这些接口的程序。

而这些接口又可以通过有线和无线的方式进行下载。比如第一部分的串口程序链接者NRF24L01无线传输模块,那么可以通过无线传输模块远程对该MCU进行程序的更新。

常用于MCU实现无线下载功能,如ESP8266wifi模块实现远距离无线下载:

由于第一部分的原因,使得Flash存储实际代码的空间将变小。


四、三种硬件电路

        由于IAP下载比较麻烦,这里不对其进行介绍,只介绍ISP/ICP里的三种常用的下载方式

4.1 串口ISP电路

        在使用串口ISP下载的时候,将BOOT0上拉接3.3V,将BOOT1接GND。最简单的电路如下图所示。 

 4.2 JTAG下载调试电路

 4.3 SWD下载调试电路

        在我们的实际生活中,SWD相比JTAG有许多优势,首先,4线(或3线)的SWD要比JTAG的引脚少的多,这就节约了许多的PCB空间。其次,SWD在高速模式下要比JTAG模式更加可。 我们在使用SWD模式时,对BOOT0和BOOT1需要做如下处理,将BOOT0悬空(或接高电平),将BOOT1经过一个10K的下拉电阻拉低。SWD模式的接口电路如下图所示。

五、参考资料

  • 为了将这一部分讲清楚本人参考了以下资料:

1、STM32F4xx参考手册

2、STM32三种启动模式_guosir_的博客-CSDN博客_stm32启动方式

3、终于明白了:STM32三种启动方式_CRUD搬砖党的神的博客-CSDN博客_stm32三种启动方式

4、单片机当中ICP与ISP有哪些不同?-电源网 

5、单片机中ICP和ISP有哪些不同?_changeyourmind的博客-CSDN博客_icp isp 区别

6、IAP的无线版(stm32无线下载程序)(基于有线升级)_沐十月id的博客-CSDN博客

7、STM32启动文件详解 | 技术部落

8、STM32启动文件详解 | 技术部落

9、浅谈堆、栈、堆区、栈区的概念和区别_蝶开三月的博客-CSDN博客_堆区

10、第3课【STM32的启动】启动模式 启动文件 启动流程_PORKWOTONLEE的博客-CSDN博客_stm32 修改启动文件

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

追逐者-桥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值