STM32的完整启动流程分析

发布者:TranquilGaze最新更新时间:2024-07-22 来源: elecfans关键字:STM32  启动流程  boot模式 手机看文章 扫描二维码
随时随地手机看文章

关于STM32的启动流程,网上有的资料在讨论几种boot模式,有的在回答启动文件的内容,在查阅了很多资料后,本文给出一个比较全面的总结和回答。

1. 根据boot引脚决定三种启动模式

1.png

复位后,在 SYSCLK 的第四个上升沿锁存 BOOT 引脚的值。BOOT0 为专用引脚,而 BOOT1 则与 GPIO 引脚共用。一旦完成对 BOOT1 的采样,相应 GPIO 引脚即进入空闲状态,可用于其它用途。BOOT0与BOOT1引脚的不同值指向了三种启动方式:

1)从主Flash启动。主Flash指的是STM32的内置Flash。选择该启动模式后,内置Flash的起始地址将被重映射到0x00000000地址,代码将在该处开始执行。一般我们使用JTAG或者SWD模式下载调试程序时,就是下载到这里面,重启后也直接从这启动。

2)从系统存储器启动。系统储存器指的是STM32的内置ROM,选择该启动模式后,内置ROM的起始地址将被重映射到0x00000000地址,代码在此处开始运行。ROM中有一段出厂预置的代码,这段代码起到一个桥的作用,允许外部通过UART/CAN或USB等将代码写入STM32的内置Flash中。这段代码也被称为ISP(In System Programing)代码,这种烧录代码的方式也被称为ISP烧录。关于ISP、ICP和IAP之间的区别将在后续章节中介绍。

3)从嵌入式SRAM中启动。显然,该方法是在STM32的内置SRAM中启动,选择该启动模式后,内置SRAM的起始地址将被重映射到0x00000000地址,代码在此处开始运行。这种模式由于烧录程序过程中不需要擦写Flash,因此速度较快,适合调试,但是掉电丢失。

总结:上面的每一种启动方式我都描述了“xxx的起始地址被重映射到了0x00000000地址,从而代码从xxx开始启动”,如下图是STM32F4xx中文参考手册中的图,可以看到类似的表述。同时,在下图中也展示了STM32F4xx中统一编址下,各内存的地址分配,注意一点,即使相应的内存被映射到了0x00000000起始的地址,通过其原来地址依然是可以访问的。

2.png

2. 启动后bootloader做了什么?

根据BOOT引脚确定了启动方式后,处理器进行的第二大步就是开始从0x00000000地址处开始执行代码,而该处存放的代码正是bootloader。

bootloader,也可以叫启动文件,无论性能高下,结构简繁,价格贵贱,每一种微控制器(处理器)都必须有启动文件,启动文件的作用便是负责执行微控制器从“复位”到“开始执行main函数”中间这段时间(称为启动过程)所必须进行的工作。最为常见的51,AVR或MSP430等微控制器当然也有对应启动文件,但开发环境往往自动完整地提供了这个启动文件,不需要开发人员再行干预启动过程,只需要从main函数开始进行应用程序的设计即可。同样,STM32微控制器,无论是keiluvision4还是IAR EWARM开发环境,ST公司都提供了现成的直接可用的启动文件。

网上有很多资料分析了STM32的启动文件的内容,在此我只进行简单的表述。启动文件中首先会定义堆栈,定义中断/异常向量表,而其中只实现了复位的异常处理函数Reset_Handler,该函数内容如下(STM32F4XX,IAR编译器),可以看到其主要执行了SystemInit和__iar_program_start两个函数,其主要功能除了初始化时钟,FPU等,还会执行一个重要功能,那就是内存的搬移、初始化操作。这是我想重点介绍的内容,同时也会回答一个疑问,就是如果从Flash启动的话,代码究竟是运行在哪儿的?在我之前接触ARM9、CortexA系列的时候,一般都是把代码搬到内部的SRAM或者外部DDR中执行的,STM32是如何呢?答案下一小节揭晓。

3.png

3. bootloader中对内存的搬移和初始化

本节针对程序在内置Flash中启动的情况进行分析。

4.png

我们知道烧录的镜像文件中包含只读代码段.text,已初始化数据段.data和未初始化的或者初始化为0的数据段.bss。代码段由于是只读的,所以是可以一直放在Flash中,CPU通过总线去读取代码执行就OK,但是.data段和.bss段由于会涉及读写为了,为了更高的读写效率是要一定搬到RAM中执行的,因此bootloader会执行很重要的一步,就是会在RAM中初始化.data和.bss段,搬移或清空相应内存区域。

因此我们知道,当启动方式选择的是从内置Flash启动的时候,代码依旧是在Flash中执行,而数据则会被拷贝到内部SRAM中,该过程是由bootloader完成的。bootloader在完成这些流程之后,就会将代码交给main函数开始执行用户代码。

  • 现在让我们思考一个问题,PC机在运行程序的时候将程序从外存(硬盘)中,调入到RAM中运行,CPU从RAM中读取程序和数据;而单片机的程序则是固化在Flash中,CPU运行时直接从Flash中读取程序,从RAM中读取数据,那么PC机能从Flash之类的存储介质中直接读代码执行吗?

  • 答案是不行。因为x86构架的CPU是基于冯.诺依曼体系的,即数据和程序存储在一起,而且PC机的RAM资源相当丰富,从几十M到几百M甚至是几个G,客观上能够承受大量的程序数据。但是单片机的构架大多是哈弗体系的,即程序和数据分开存储,而且单片的片内RAM资源是相当有限的,内部的RAM过大会带来成本的大幅度提高。

4. ISP、IAP、ICP三种烧录方式

虽然这个小节稍稍偏题,但是由于上面在3中启动方式中介绍过了ISP烧录,因此一并在此介绍剩下的两种烧录方式。

1)ICP(In Circuit Programing)。在电路编程,可通过CPU的Debug Access Port 烧录代码,比如ARM Cortex的Debug Interface主要是SWD(Serial Wire Debug)或JTAG(Joint Test Action Group);

2)ISP(In System Programing)。在系统编程,可借助MCU厂商预置的Bootloader 实现通过板载UART或USB接口烧录代码。

3)IAP(In Applicating Programing)。在应用编程,由开发者实现Bootloader功能,比如STM32存储映射Code分区中的Flash本是存储用户应用程序的区间(上电从此处执行用户代码),开发者可以将自己实现的Bootloader存放到Flash区间,MCU上电启动先执行用户的Bootloader代码,该代码可为用户应用程序的下载、校验、增量/补丁更新、升级、恢复等提供支持,如果用户代码提供了网络访问功能,IAP 还能通过无线网络下载更新代码,实现OTA空中升级功能。

4)IAP和ISP 的区别。

a、ISP程序一般是芯片厂家提供的。IAP一般是用户自己编写的

b、ISP一般支持的烧录方式有限,只有串口等。IAP就比较灵活,可以灵活的使用各种通信协议烧录

c、isp一般需要芯片进行一些硬件上的操作才行,IAP全部工作由程序完成,不需要去现场

d、isp一般只需要按格式将升级文件通过串口发送就可以。IAP的话控制相对麻烦,如果是OTA的话还需要编写后台的。

e、注意,这里介绍的bootloader功能显然跟之前介绍的启动文件bootloader有所区别,其目的是为了能接受外部镜像进行烧录,而不是为了运行普通用户程序。


关键字:STM32  启动流程  boot模式 引用地址:STM32的完整启动流程分析

上一篇:STM32CUBEIDE(1)----安装
下一篇:STM32_ DAC输出电压

推荐阅读最新更新时间:2024-11-12 23:30

STM32的时钟系统
STM32(CORETEX-M3)有5中时钟源:HSI、HSE、LSI、LSE、PLL (1)HSI是高速内部时钟,又叫RC振荡器,晶振频率为8MHZ,精确度不高。 (2)HSE是高速外部时钟,可接石英、陶瓷谐振器;也可接如外部时钟信号,范围为4-16MHZ。 (3)LSI是低速内部时钟,RC振荡器,频率为40KHZ,提供低功耗时钟。 (4)LSE是低速外部时钟,外接频率为32.768KHZ石英晶体。 PLL为锁相环倍频输出,其时钟输入源可为HSI、HSE、HSE/2。倍频可选择2~16倍,最大不超过76MHZ。 sysclk的时钟来源:HSI、HSE、PLL 实时时钟 stm32的实时时钟是一个独立的定时器,这个定时器可以连
[单片机]
<font color='red'>STM32</font>的时钟系统
Stm32的ADC功能介绍及相关代码
特性 此图来自中文参考手册,作为下面的整体概述。 ADC正常工作时的电路连接: ADC的内部结构图: 从上面的内部结构图可以看出stm32与其他低端的单片机不同的地方是:可以通过定时器事件触发ADC的转换,但只支持注入通道。那么注入通道和规则通道又是什么? 注入通道与规则通道: 上面的图形象的说明了注入通道与规则通道的区别:规则通道相当于正常的程序运行一通道完成后接着另一通道(当然这要开启连续或者扫描模式才行),而注入通道相当于程序的中断,也就是说它可以打断规则通道的ADC转换去优先转换另一条同的ADC转换;比如说在连续转换中现在转换到了2通道,此时因为定时器事件发生触发ADC去转换配置为注入通道的通道4,转
[单片机]
<font color='red'>Stm32</font>的ADC功能介绍及相关代码
STM32—中断详解(配合按键中断代码,代码亲测)
在STM32中执行中断主要分三部分: 1.配置NVIC_Config()函数 2.配置EXTI_Config()函数 3.编写中断服务函数 (注:本文章所用代码为中断按键代码,实现了按键进入中断从而控制LED亮灭) 配置NVIC_Config()函数 NVIC 是嵌套向量中断控制器,控制着整个芯片中断相关的功能,它跟内核紧密耦合,是内核里面的一个外设。 NVIC_Config()函数代码如下: static void NVIC_Config(void) /* 主要是配置中断源的优先级与打开使能中断通道 */ { NVIC_InitTypeDef NVIC_InitStruct ; /* 配置中断优先级分组(设置抢占
[单片机]
<font color='red'>STM32</font>—中断详解(配合按键中断代码,代码亲测)
STM32之独立看门狗 学习笔记
一、独立看门狗概述: 独立看门狗其实就是一个独立于主时钟的定时复位狗。一旦开启独立看门狗,它就会根据自己设定的时间不断倒数,倒数到0后就开始复位。 二、关于喂狗: 喂狗就是让狗去吃东西,分心后,这只狗就得重新倒数。 三、stm32看门狗示例程序: #include led.h #include delay.h #include key.h #include sys.h #include usart.h void IWDG_Init(u8 prer,u16 rlr) { IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //使
[单片机]
玩转STM32(6)初识编译环境
前面已经介绍了怎么样找到项目的工程文件,只要双击那个文件就可以打开整个项目工程,进入代码开发调试环境。在很多年以前,开发软件还是很困难的事情,因为那时候编译环境非常不友好,不是图形界面,而是基于文本的界面,并且还不是集成开发环境,是分离的。当你在编辑器里写了代码之后,然后再保存成文件,然后退出编辑器,再来到命令行的环境下面,输入调用编译器的命令,才可以编译源码。如果编译有问题,要先把出错的行号和列号记住,再进入编辑器进行代码修改,就这样来来回回,反反复复地进行着,可想而之,那时的开发效率是多么的低下,需要人的记性超级好,耐心也要经得起考验,才可以成为开发人员。到今天这个时代,已经大为改观,整个开发环境已经是集成开发环境了,非常便捷
[单片机]
玩转<font color='red'>STM32</font>(6)初识编译环境
简述stm32的usart的功能特点
关于STM32的启动流程,网上有的资料在讨论几种boot模式,有的在回答启动文件的内容,在查阅了很多资料后,本文给出一个比较全面的总结和回答。 1. 根据boot引脚决定三种启动模式 复位后,在 SYSCLK 的第四个上升沿锁存 BOOT 引脚的值。BOOT0 为专用引脚,而 BOOT1 则与 GPIO 引脚共用。一旦完成对 BOOT1 的采样,相应 GPIO 引脚即进入空闲状态,可用于其它用途。BOOT0与BOOT1引脚的不同值指向了三种启动方式: 从主Flash启动。主Flash指的是STM32的内置Flash。选择该启动模式后,内置Flash的起始地址将被重映射到0x00000000地址,代码将在该处开始执行。一般我
[单片机]
简述<font color='red'>stm32</font>的usart的功能特点
STM32 清读保护
stm32写错程序了,那么你的程序里面又是自动写读保护的,而且你的管教又是接死,不能更改boot模式,这种情况下,以前我是换一个芯片,后来看到网上有人用ram运行程序方法解决。 keil中,程序 int main(void) { FLASH_Unlock(); FLASH_ReadOutProtection(DISABLE); while(1); } 在Target页面设置rom的地方,有个irom的本来设置指向flash的0x80000000的,改为指向ram,0x20000000。 当然ram的指向也要修改一下,不能0x20000000开始了,改了0x20001000开始吧。 在debug页面下,在init
[单片机]
STM32 PWM输出函数
1、参考资料 《STM32F1开发指南-库函数版本》-第14章 PWM输出实验 《STM32中文参考手册V10》-第14章 通用定时器 2、STM32 PWM工作过程 ·STM32 PWM工作过程(通道1为例) CCR1:捕获比较(值)寄存器(x=1,2,3,4):设置比较值。 CCMR1: OC1M 位: 对于PWM方式下,用于设置PWM模式1【110】或者PWM模式2【111】 CCER:CC1P位:输入/捕获1输出极性。0:高电平有效,1:低电平有效。 CCER:CC1E位:输入/捕获1输出使能。0:关闭,1:打
[单片机]
<font color='red'>STM32</font> PWM输出函数
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved