STM32 MCU启动会的流程和方案流程

找到stm32f10x的外设库下载(官网需要注册才能下载)

从官网下载到stm32f10x的外设库解压将得到如下文件

_htmresc—包含一些图片,没什么用;

Utilities—评估板代码没什么用。

在 SystemInit 函数中调用SetSysClock()对系统时钟进行配置在SetSysClock()函数中根据设定的宏对时钟进行不同的配置,默认是外部8MHz晶振倍频到72MHz。

就是bootladder任务一开始0.2秒以后,将启動会的流程和方案标志位设为app启动会的流程和方案如果下载完成,则将启动会的流程和方案标志设为任务二启动会的流程和方案在这の前如果断电,说明下载未完成启动会的流程和方案后重新执行app任务。


任务一完成后重启进入bootladder任务二,更新app程序在此期间断电的话,重启进入的还是bootladder任务二重新更新app程序,直到完成后设启动会的流程和方案标志为app任务。

那么bootloadder任务二里没有必要再设置一遍启动会嘚流程和方案标志吧?

首先我们需要澄清一个问题什麼是 Startup Code,什么是 Bootloader因为总看到有同学混用这两个概念。

Bootloader 可以译为引导程序早期的单片机是没有 Bootloader 这种概念的。如大家熟悉的 MCS51最初芯片内是鈈能存储代码的,需要外挂EPROM就是下面这种带个小玻璃窗的存储器。擦除 EPROM 中的代码需要用紫外线照射几分钟才行

这种可电擦写的存储器,并集成在了单片机内部但出厂的时候单片机的程序存储区仍然是空白的,没有任何代码用户编译程序后,下载到单片机后才能运行那么在产品发给用户后,如果发现有Bug怎么办呢就得用编程器把新代码重新下载一次。这实在是有点儿麻烦特别是如果客户距离很远嘚话。于是有聪明的程序猿想了一个办法写一小段特殊的代码放在程序里,这段代码可以通过一定方式比如用按键触发进入运行,它鈳以通过串口(早期的 PC 串口是标配)接收新的代码并写入Flash从而在没有硬件编程器的情况下也能完成代码的更新。

程序猿们也是现代历史前进嘚重要推动力啊!

后来有芯片厂商把这种代码在出厂时就固化在芯片里,极大的方便了代码下载和程序更新STM32F030内部就固化了Bootloader。当我们把┅个引脚 BOOT0 拉高的同时重新给芯片上电或复位,就会触发Boootloader进入运行此时我们通过单片机的串口就可以把新程序发送给单片机,发送完后紦 BOOT0 拉低再复位单片机,新程序就会运行起来

Startup Code 可以译为启动会的流程和方案代码。单片机上电或复位后最先执行的一段代码一般主要會完成堆栈指针的设置,复位向量的获取和加载然后初始化变量,最后跳转到用户代码在详细看启动会的流程和方案代码之前,我们先看一下 STM32F030 的内存映射

下面是 STM32F030 的内存映射,其它芯片会因为 FlashSRAM 空间大小不同而略有不同。

这是采用32位机的好处地址空间足够用。不像8位戓16位机很容易出现地址空间不够用,动不动就需要用 Page 来间接寻址

我们从低地址到高地址逐段看一下:

这段地址空间,会因为不同的 BOOT 模式洏映射到不同的物理内存。

当芯片复位或从 Standby 低功耗模式唤醒时:

如果引脚 BOOT0 是被拉低的,将映射到 Flash memory这是最常用的代码运行模式;

注:nBOOT1 为Flash寄存器中的一位,用户何以设置

存放 bootloader, 片内集成温度传感器的校正数据,和片内集成电压参考的校正数据

这些代码和数据是在工厂固化好嘚

存放用户变量,堆(Heap)和栈(Stack)也可以把代码加载到 SRAM 运行。

芯片集成的外设如 USART, SPI, GPIO等的寄存器地址在这一区域。

我们还是以下面这个最简单的GPIO翻转代码为例:

把此工程下载到单片机后用调试器观察下面两个地址的内容:

我们会发现0x开始的区域, 和0x开始的区域,内容完全相同这說明 Flash 区的内容映射到了 0x起始的这一段地址区域。

不同于 MCS51 在 0x0000 放的是复位向量STM32F030 还有其它 ARM 芯片在零地址存放的是初始堆栈指针地址。

0x: (0x) 复位向量上电或复位后最先加载入PC

注:单片机上电或复位后,堆栈指针初始化和 PC 初始值的加载总是从地址 0xx获取在上面这种用户模式下,实际是從 Flash 区的 0xx 获取的

我们可以通过调试器观察一下芯片复位后 M0 内核的寄存器:

细心的同学这时可能发现了一个问题。

堆栈指针 SP 的内容和前面存儲器中的内容是对的上的但是 PC 里的内容好像对不上啊?PC 里的值是 0x,存储器里明明是 0x 啊!

这里牵涉到了 ARM 体系里的两种工作状态 ARM 和 ThumbARM 状态下执荇32位指令,Thumb状态下执行16位指令那么如何在这两者之间切换呢,一个方法就是靠跳转地址的最低位(Bit0), 当 Bit0 设为 1 时进入 Thumb 状态当 Bit0 设为 0 时进入 ARM 状态。

对于单片机来说16位的 Thumb 指令就足够了,而且16位指令比32位指令能节省存储器空间所以 M0 内核只支持 Thumb 指令。

到这里我们就可以理解复位向量為什么是 0x 了

接下来我们来看复位向量 0x 指向的第一条指令:

单片机将要执行的第一条指令 0x4804,这是什么意思呢

先说结论:它就是下图中,單片机复位后光标指向的这条指令:

在这里详细解释一下 0x4804 这条指令:

它对应的机器码是 0100

注意PC的值是当前地址+4

SystemInit( ) 这个函数在 system_stm32f0xx.c 这个文件里,主偠完成系统时钟的初始化可以点进去看一下具体的内容。

函数 SystemInit( ) 执行完之后程序跳转回来,取得 __main( ) 函数的地址跳转到 __main() 函数执行。需要注意这个函数不是我们用户代码里的 main( ) 函数。

__main() 函数执行完基本工作就做完了,这才跳转到用户代码的 main( ) 函数

欢迎关注我们,微信公众号:TopSemic

我要回帖

更多关于 启动会的流程和方案 的文章

 

随机推荐