详细的STM32启动配置流程解析

发布者:SereneSunset最新更新时间:2024-08-09 来源: elecfans关键字:STM32  启动配置 手机看文章 扫描二维码
随时随地手机看文章

大家不妨设想一下,cpu 的工作是什么,cpu 是没有主观意识的,它只会按照特定的指令执行相应的操作,用专业术语来说就是:取指 -> 译码 -> 执行,译码和执行肯定是在 cpu 内部进行操作的,并且前提是已经取到了指令。那现在问题来了,指令在哪?

d3d5cafc-17aa-11ee-962d-dac502259ad0.png

cpu上电复位后执行的第一步操作就是取指令

问题1:指令存储在何处

我们在电脑上编写的程序最终是要烧写到芯片内部的 FLASH中(此处特指STM32)。

问题2:如何将可执行文件烧写至 FLASH 上

STM32 的启动方式有很多种,从主存 FLASH 启动,从 system memory 启动,从 SRAM 中启动。

问题3:从 SRAM 中启动,为什么需要重新设置中断向量表

接下来,我们将围绕这三个问题进行解答

猜想

既然 cpu 上电复位后第一步操作就是取指令,那么这个指令肯定是存储在掉电不丢失的存储介质上(rom、flash)。

猜想1:指令存储在掉电不丢失的存储介质上

我们最终生成的、cpu可以执行的可执行文件肯定是要通过某种外设将用户程序烧写到 FLASH 上,这一点肯定是毋庸置疑的,因为 cpu 与外围设备进行数据交互的时候是通过外设控制器来进行的。

猜想2:通过某种外设将可执行文件烧写至 FLASH 上

STM32 的 FLASH 基地址为 0X0800 0000 ,SRAM 基地址为 0X2000 0000。可不可能是因为这两个存储介质的地址不同,所以才要重新设置中断向量表。 因为我们都知道,中断向量表的首地址就是程序的入口地址。

猜想3:可能与基地址有关

实验验证

实验前必备知识

1. XIP设备 eXecute In Place,即芯片内执行,指应用程序可以直接在 flash 闪存内运行,不必再把代码读到系统 RAM中。在我们的印象里,应用程序必须要从硬盘中加载到内存当中才可以被运行,但实际上应用程序是可以直接在flash 闪存运行的,也就是说,cpu 可以直接从 flash 中取出指令。对于 STM32 而言,它是有 XIP 设备的。 STM32F1 内存图

d406f244-17aa-11ee-962d-dac502259ad0.png

如上图所示,FLASH、SYSTEM MEMORY、OPTION BYTES 都是STM32内部的XIP设备。 F1 内存图信息不是很全,再看下 F4 的内存图。 STM32F4内存图:

d42be0fe-17aa-11ee-962d-dac502259ad0.png

我们可以看到,不论是 F1 还是 F4,XIP 设备都属于内存图中的 BLOCK0 区域内。 这样我们大概就知道了 STM32 内部的 XIP 设备在 0x0000 0000 ~ 0x1FFF FFFF 内。 上述的内存图是通过映射的方式将芯片的框图进行映射得到的,也就是说,上述这幅图是为了开发人员更好地面向芯片编程而抽象出来的一幅图。我们先来看下面这副图 STM32F1框图:

d45475c8-17aa-11ee-962d-dac502259ad0.png

STM32F4框图:

d48c85f8-17aa-11ee-962d-dac502259ad0.png

对比两幅框图可以看出,F4 比 F1 复杂很多,特别体现在外设上,架构还是差不多的。

d4b8abec-17aa-11ee-962d-dac502259ad0.png

红色箭头所指向的就是译码电路。 如果你学过微机原理,那么你肯定知道,外设是通过译码电路连接到地址总线上,每一个外设都有其相对应的内存范围,当 cpu 发出的地址信息处于某一个外设的地址范围内,就选中了该外设,cpu就可以与该外设进行数据交互。 一个外设对应一个内存范围,那所有的外设结合起来,是不是就是对应一张图了。

2. STM32 启动配置 在 STM32F10xxx 里,可以通过 BOOT[1:0] 引脚选择三种不同启动模式。

d4f1929a-17aa-11ee-962d-dac502259ad0.png

在系统复位后,SYSCLK 的第 4 个上升沿, BOOT 引脚的值将被锁存。用户可以通过设置 BOOT1 和 BOOT0 引脚的状态,来选择在复位后的启动模式。 在启动延迟之后, CPU 从地址 0x0000 0000 获取堆栈顶的地址,并从启动存储器的 0x0000 0004 指示的地址开始执行代码。(这里先不验证,在之后的博客中会进行验证,但你需要记住,后面用的上) 因为固定的存储器映像,代码区始终从地址 0x0000 0000 开始(通过 ICode 和 DCode 总线访问),而数据区(SRAM)始终从地址 0x2000 0000 开始(通过系统总线访问)。Cortex-M3 的 CPU 始终从 ICode 总线获取复位向量,即启动仅适合于从代码区开始(典型地从 Flash 启动)。STM32F10xxx 微控制器实现了一个特殊的机制,系统可以不仅仅从 Flash 存储器或系统存储器启动,还可以从内置 SRAM 启动。 根据选定的启动模式,主闪存存储器、系统存储器或 SRAM 可以按照以下方式访问:

从主闪存存储器启动:主闪存存储器被映射到启动空间(0x00000000),但仍然能够在它原有的地址(0x08000000)访问它,即闪存存储器的内容可以在两个地址区域访问, 0x00000000 或 0x08000000。

从系统存储器启动:系统存储器被映射到启动空间(0x00000000),但仍然能够在它原有的地址(互联型产品原有地址为 0x1FFFB000 ,其它产品原有地址为 0x1FFFF000 )访问它。

从内置 SRAM 启动:只能在 0x20000000 开始的地址区访问 SRAM(当从内置 SRAM 启动,在应用程序的初始化代码中,必须使用 NVIC 的异常表和偏移寄存器,重新映射向量表到 SRAM 中)。

一般情况下都是从主闪存模式启动的,也就是用户代码被烧写到 0x08000000 地址处。 内嵌的自举程序 (Bootloader) 内嵌的自举程序存放在系统存储区,由 ST 在生产线上写入,用于通过可用的串行接口对闪存存储器进行重新编程,也就是这个自举程序在出厂的时候就已经固化了。大家可以想一下内嵌的自举程序的作用是什么?想不出来也没关系,后面会讲到。 如果想要详细了解这个自举程序到底干了什么,可以看下官方文档: STM32 microcontroller system memory boot mode 3. 可执行文件的形成过程 STM32 | hex文件、bin文件、axf文件的区别? 大家可以看下这篇博文,写的还是挺不错的!描述了最终烧写到STM32中的可执行代码的形成过程。 4. 三种复位

硬件复位

顾名思义通过硬件给系统一个复位,比如在电路板上设计一复位电路,通过按下按键就可以给系统实现一个复位,而无论系统在执行什么样的程序。复位后初始化一些配置芯片,硬件复位的作用区域一般是全局的。

软件复位

是通过软件给系统一个复位信号,如低电平或许是高电平(具体看系统设置)来实现复位操作软件复位一般是一些块结构复位。

上电复位

系统在上电的瞬间就执行复位操作, 上电复位里面包括硬件复位和软复位的操作,硬件复位和软复位是从上电复位里面的某点开始的启动操作。 复位需要初始化CPU系统,包括CPU和内存等。

验证猜想

1. 验证猜想-1 对于猜想1,其实不需要验证。代码肯定是要存储在掉电不丢失的存储介质上,否则,每次重新上电都要重新烧写程序,这是与事实相反的。而在实验前必备知识中,我们了解到 STM32 内部的 XIP 设备,那不就是代码存储的地方吗?并且也在 STM32 启动方式中详细地描述了代码存储位置。

如果从主FLASH启动,用户代码存储在0X 0800 0000

如果从 SYSTEM MEMORY 启动,里面存储的是 Bootloader,是芯片出厂的时候就已经固化好了的,可以从中读数据,但是不可以向其中写数据,它的作用就是:将用户程序通过可用的外设烧写到指定的地址处,然后启动 STM32。

如果从 SRAM 启动,用户代码存储在 0X2000 0000

2. 验证猜想-2 实验前的必备知识中已经大概地描述了最终烧写到 STM32 中的可执行文件的形成过程,现在我们需要验证的就是如何将可执行文件烧写到指定的存储设备中去(假设是 FLASH,其实也可以是 SRAM) 我第一次使用 Flymcu(串口下载软件的时候),我脑海里就有一个疑问,就是这个软件到底是怎样使得 STM32 将生成的代码烧写到内部 FLASH 上的。这真的是很不可思议!因为 STM32 上电复位后肯定是要执行代码的,可是我还没有给它代码呢,它怎么会运作呢?当时我真的很迷惑。 其实,STM32 出厂的时候 Bootloader(用于将用户程序下载到 STM32 内部指定地址处的固件(程序))就已经固化在了 System Memory 上了,可读写无效。 从 STM32 启动配置一节中我们知道,可以通过对 BOOT1 和 BOOT0 引脚上高低电平的改变从而实现 STM32 启动方式的不同。

d5110bd4-17aa-11ee-962d-dac502259ad0.png

如上所说,Bootloader 存储在 Sytem Memory 上,如果想要让 Bootloader 运行(将用户程序下载到指定内存地址处),那启动模式肯定是要选择以系统存储器的方式启动。

BOOT1 = 0    BOOT0 = 1 -> 系统存储器模式

因此,外部电路的设计的目的就是要能够达到能够对 BOOT1 和 BOOT0 引脚上高低电平改变的能力。 接下来,我们就以正点原子的原理图(探索者)为例,来看下 STM32 外部的电路到底是如何设计的,以及Flymcu 到底是怎样控制 BOOT1 和 BOOT0 引脚上高低电平改变从而达到具有使得 STM32 从系统存储器启动的的神奇能力。

d540199c-17aa-11ee-962d-dac502259ad0.png

如上图所示,这就是正点原子探索者一键下载电路。 一键下载电路涉及到模电知识,下面这篇文章写的还不错,并且还描述了CH340G芯片引脚的作用和功能。 stm32一键下载电路(下一篇文章) 从上图我们可以知道,Flymcu 肯定是通过 usb 线将数据或指令写入 CH340G 内(CH340 D + CH340 D- )然后CH340G 根据来自 usb 的指令进行相应的工作。 CH340G在此电路中的工作就两个:

与STM32进行数据交互

控制BOOT0和RESET高低电平的变化

特别注意:正点原子探索者BOOT0和BOOT1引脚默认都是接地

d5768662-17aa-11ee-962d-dac502259ad0.png

BOOT0、BOOT1是通过跳线帽和地进行连接的 现在我们知道了,控制 BOOT1 和 BOOT0 引脚上高低电平改变是 CH340G 的作用,而 CH340G 是严格按照来自Flymcu 的指令进行的,所以,控制 BOOT1 和 BOOT0 引脚上高低电平改变的幕后黑手就是 Flymcu。 注意:向 FLASH 中烧写程序不仅仅只有串口,由于硬件平台的限制,因此分析串口下载。 问题来了,那 Flymcu 到底干了什么,它是如何将用户程序烧写的 STM32 内部指定地址处? 以跑马灯为例,看下Flymcu烧写程序过程中输出的信息。

d5869458-17aa-11ee-962d-dac502259ad0.png

DTR 电平置低:复位

RTS 电平置高:进入 Bootloader

延时 100ms :有谁能够告诉我为什么

DTR 电平置高:释放复位

RTS 维持高 :此时开始运行 Bootloader

开始连接 :Flymcu 要与 STM32 连接肯定是要发送特定的指令,并且当 STM32 接收到预先约定好的指令时,也会发送特定的回复。(和接头的性质差不多)

注意:STM32 从 Bootloader 启动到能够与外部设备进行数据交互需要一定的时间,因此连接需要一定的时间

读出关于芯片相关的数据

读出选项字节

进行全片擦除,去除写保护,再次重启 Bootloader(有大佬能告诉我为什么)

编写程序,从 0x0800 0000 处开始运行

上述的过程中,大家比较疑惑的地方就是,Flymcu 发送给 STM32 的指令到底是什么,这个指令肯定是事先就确定好的,在这个文档中提及到了。 stm32 microcontroller system memory boot mode 这个手册中的内容大家可以自己详细地去看下,内容不多,我就粗略地说一下必要的知识点。 硬件连接需要(文档中的第35页) 通过串口与外部设备进行数据交互时STM32外部电路设计。

d5b69ea0-17aa-11ee-962d-dac502259ad0.png

通过 DFU 与外部设备进行数据交互时 STM32 外部电路设计

d5b69ea0-17aa-11ee-962d-dac502259ad0.png

还有其他的连接方式,我想表述的意思就是: Bootloader 与外部设备进行数据交互的方式有很多种,不仅仅只有串口,只是由于硬件平台有限(正点原子只有通过串口下载的接口(调试接口除外))而根据不同的交互方式,STM32 外部的电路设计又大不相同。 Bootloader启动流程

d5f471d0-17aa-11ee-962d-dac502259ad0.png

从启动流程中我们就可以得到Flymcu发送给STM32的特定连接指令为:0x7F。 STM32F40xxx/41xxx devices bootloader version

d61927a0-17aa-11ee-962d-dac502259ad0.png

通过版本信息中红色画线部分可以得知,当 Bootloader 接收到相应的命令之后,就会连续发送两个 response。我们这个时候再看下 Flymcu 中的输出信息,

d6516908-17aa-11ee-962d-dac502259ad0.png

通过红色画线部分可以看出,Flymcu 接收到两个来自 Bootloader 的信息。 此时,接头成功!!!!! 接头成功后肯定就可以进行数据交互了!!! 因此,我们最初的猜想是正确的:即 STM32 通过某种外设将可执行文件烧写至 FLASH 上(也可以是 SRAM) 验证猜想-3 博客当中已经多次提及到,STM32 不仅可以从 FLASH 上启动,还可以从 SRAM 上启动。并且在STM32启动配置中有一个小提示:从 SRAM 中启动,需要重新设置中断向量表。 中断向量表的设置是用户在用户程序中自己实现的!!! 要验证这个猜想,可以从 SRAM 中启动,但是不设置中断向量表,看一下会出现什么情况。

d6812206-17aa-11ee-962d-dac502259ad0.png

由于正点原子的电路设计(因为我使用的就是正点原子的探索者开发板),使得无法通过串口进行 SRAM 启动,只能通过调试接口下载程序。

注意:SRAM是掉电数据就会丢失的存储器介质,因此使用时(前提是已经掉电)要重新下载程序从 SRAM 中启动的最主要的目的是用来调试程序,产品中的用户程序肯定都是存储在 FLASH 上的,不然每次掉电后用户程序都没了!!!

如何通过调试接口将用户程序下载到 SRAM 处,可以参考一下下面两篇博文:

STM32 内部 SRAM 调试程序

在 SRAM 中调试代码

假设你现在已经实现了能够通过调试接口将用户程序下载到 SRAM 处,那么接下来,我们来验证一下。如果没有重新设置中断向量表会出现什么结果。 得出结论,总结归纳 对于最开始提出的三个猜想,现在可以得出结论:

指令存储在掉电不丢失的存储介质上

STM32 通过某种外设将可执行文件烧写至掉电不丢失的存储介质上

中断向量表的首地址就是程序的入口地址

注意: 通过串口下载程序,实际上是 Flymcu(上位机)与 STM32 内置的 Bootloader 进行数据交互,但两者直接需要特定的硬件环境(CH340G(USB转串口芯片)) 注意: 内存图中的 reserved 有些是不使用,有些是不能用(有其他重要的作用:可读写忽略),不可以修改其值 看完这篇博客,你的脑海里必须得有一个流程的框架:

用户面向单片机编写用户代码(C,C++,ASM)

用户代码通过交叉编译工具链生成单片机可以执行的可执行文件(HEX,BIN,AXF)

上位机:各种烧写工具(不局限于 Flymcu (因为 Bootloader 与外部设备进行数据交互不仅仅只是通过USART)))与单片机内部的 Bootloader 进行数据交互(目的是将可执行文件下载到指定的存储地址处)

将可执行文件下载到指定存储地址处,然后还会继续等待上位机的 command,可以通过复位或上位机发送跳转到用户代码入口地址的命令执行用户程序。 这个流程的框架总结一句话就是: 可执行程序 -> cpu执行第一条用户代码的流程 至于 cpu 执行第一条用户代码之后的流程后面的博客会详细说明,但毋庸置疑的是,这是一个重要转折点,在这个点之后执行的是你自己编写的代码,你比较熟悉这个过程,但是在这个点之前,对大部分人来说都是都是比较陌生的,但是但你对这个过程了解之后,会对你的知识体系有非常大的提升。 希望这篇博客对你有所帮助。

关键字:STM32  启动配置 引用地址:详细的STM32启动配置流程解析

上一篇:STM32F407 基本定时器使用
下一篇:独立看门狗的理解

推荐阅读最新更新时间:2024-11-17 15:38

STM32 使用DMA+DAC+TIMER输出正弦波
之前已经简单论述过,根据我个人菜鸟的了解与认识,对之前的知识进行整理回顾: DMA:我的理解就是一个通道,或者是一座桥梁。在静态内存到静态内存,或者外设到静态内存间的一个通讯的通道。建立这个通道的好处是:可以抛开CPU,不占用CPU的资源,直接使用这块内存的内容,速度也会加快。 DAC:STM32F103中有两个DAC,可以同时使用。DAC的作用就是将数字量转化为模拟量(电压),在这就不作太多的讲解。 TIMER:定时器。不作讲解。 那么对于使用DMA+DAC+TIMER产生正弦波的原理或过程,我有这样一个简单的理解:先将一个可以生成正弦波的数据表保存在静态内存中,然后在DAC以及这块内存中间使用DMA建立一个通道
[单片机]
STM32学习第三课:STM32 c语言学习基础3(内存操作、指针、结构指针)
1.内存操作 在对内存操作头疼的时候我发现了这篇神奇的文章,拜读之后豁然开朗心生崇拜 数据指针 在嵌入式系统的编程中,常常要求在特定的内存单元读写内容,汇编有对应的MOV指令,而除C/C++以外的其它编程语言基本没有直接访问绝对地址的能力。在嵌入式系统的实际调试中,多借助C语言指针所具有的对绝对地址单元内容的读写能力。以指针直接操作内存多发生在如下几种情况: (1) 某I/O芯片被定位在CPU的存储空间而非I/O空间,而且寄存器对应于某特定地址; (2) 两个CPU之间以双端口RAM通信,CPU需要在双端口RAM的特定单元(称为mail box)书写内容以在对方CPU产生中断; (3) 读取在ROM或FLA
[单片机]
<font color='red'>STM32</font>学习第三课:<font color='red'>STM32</font> c语言学习基础3(内存操作、指针、结构指针)
STM32 之位带操作
Cortex-M3 支持了位操作后,可以使用普通的加载/存储指令来对单一的比特进行读写。   在 CM3 支持的位带中,有两个区中实现了位带。   其中一个是 SRAM 区的最低 1MB 范围, 0x20000000 ‐ 0x200FFFFF(SRAM 区中的最低 1MB);   第二个则是片内外设区的最低 1MB范围, 0x40000000 ‐ 0x400FFFFF(片上外设区中的最低 1MB)。   这两个区中的地址除了可以像普通的 RAM 一样使用外,它们还都有自己的 位带别名区 ,位带别名区把每个比特膨胀成一个 32 位的字。当你通过位带别名区访问这些字时,就可以达到访问原始比特的目的。   CM3 使用如下
[单片机]
stm32专题二十九:Flash 读写保护
设置Flash的读写保护,其实就是操作内部Flash的选项字节。 选项字节在内部Flash的主存储页之后,由于是Flash,不能像内存RAM一样随意写入。由于Flash的写入特性,只能将 1 写成 0,而如果要确保写入数据的绝对正确,则需要先擦除再写入。如果直接对Flash写入,则只能确保写入 0 值是正确的。 选项字节,可以认为是掉电不会丢失的寄存器(Flash空间)。就是用Flash介质来存储配置,要修改选项字节,跟修改Flash一样。 RDP 读保护字节描述(可以通过j-link或st-link读Flash 加密等): RDP配置方式: 2个数据字节 Data0 Data1 3 设置写保护 RDP
[单片机]
<font color='red'>stm32</font>专题二十九:Flash 读写保护
STM32 UART串口通讯编程方法
在对通讯时间要求比较高的时候,就需要自己对UART的通讯底层直接进行操作。我以STM32单片机为例,讲一下比较快速的UART编程方法。——其实不止是STM32这么处理,我以前使用过51的单片机,TI的MSP单片机,三菱的16位单片机,都可以采用这种方法。 基本的处理思路如下: 1. UART接收的处理方法 打开UART的接收中断,每收到一个字节就放到接收缓冲区,同时更新接收指针。当连续100ms没有收到接收字符,则认为本次帧接收完毕,置位帧接收完成标志,由主程序进行处理。 2. UART发送的处理方法 将需要发送的数据放到发送缓冲区,设置发送长度。然后发送第一个字节,并打开发送中断。在发送中断中判断是否已经发送
[单片机]
STM32烧写方法一】ST-LINK烧写
首先烧写就是将你写好的程序下载到单片机的芯片里,这篇提供2中烧写方法! 第一种为ST-LINK烧写: STLink的JTAG接口在SWD模式下载时理论上需要4根数据线就okay了SWCLK,SWDIO,GND,VCC。 我们只需要上面的 19、20 、7、9 脚即可!至于管口的确定你可以根据上电后的电压来判断! 将上面的口连接到STM32芯片上的对应口,再将芯片上电!记住一定要上电! 然后到keil里做下面选择: ort选择SW 就可以编译烧写程序了!
[单片机]
【<font color='red'>STM32</font>烧写方法一】ST-LINK烧写
STM32的TIM作为普通定时器的方法
以stm32的TIM2作为例,将其配置成为普通的定时器,计时时间到即触发中断。 1:对定时器的基本配置 先声明一个定时器配置用的结构体变量TIM_TimeBaseStructure,具体可以参考STM32提供的TIM库 TIM_TimeBaseStructure.TIM_Period = 65535; //设置自动装载寄存器 TIM_TimeBaseStructure.TIM_Prescaler = 100; //分频计数 TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_Cou
[单片机]
意法与厦门大学合作研发32位嵌入式系统
  微控制器设计开发的领导厂商意法半导体(ST)协同其增值服务商深圳市博巨兴,宣布与厦门大学签订合作协议,成立“ST嵌入式系统联合实验室”,并举行实验室揭牌仪式。意法半导体持续推动校园合作计划,与中国的大学携手开发嵌入式应用技术和培训电子工程专业学生,再迈出重要的一步。   作为32位微控制器的主导厂商之一,意法半导体将向厦门大学提供先进的基于32位ARM Cortex-M3的STM32微控制器及其开发工具,信息科学与技术学院(通信工程系、电子工程系、自动化系、计算机系及智能科学与技术系)的本科生及研究生将参与意法半导体的实际项目的开发。此外,意法半导体将提供所需的全部培训和技术支持,从事教学和学术研究,协助大学院校及产业界培
[医疗电子]
小广播
设计资源 培训 开发板 精华推荐

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

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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