很多刚学STM32、嵌入式的同学,都会被一堆名词绕晕:ARM架构、Cortex-M内核、MCU、SoC、BOOT、串口刷机、ST-Link下载……它们到底是什么关系?为什么STM32是ARM内核,但不是ARM公司生产的?为什么BOOT0拉高能救砖?
一、ARM生态链:只授权IP,不做实体芯片
由于一些历史和商业原因,ARM并没有像英特尔一样自己既设计芯片、又做实体芯片,而是只设计指令集架构,然后依托于该架构设计芯片图纸。(这里的芯片指的是CPU,而非其他控制器芯片)。
整个ARM生态是一套完整的分工体系,分为三个层次:
(1)第一层:ARM公司—定架构、画内核
ARM的核心工作只有两件事:
-
定义指令集架构:ARMv6、ARMv7、ARMv8等,相当于CPU的“底层语法规则”,规定CPU能识别哪些指令、怎么运算、怎么寻址。
-
设计CPU内核IP:基于对应架构,设计出可商用的内核图纸,也就是我们常说的Cortex-M0、M3、M4、M7、A7等。
其中指令集架构是随着发展不断推陈出新的,很有可能前后不同的版本不兼容。更重要的是:ARM即使同一个版本,如果分为了Cortex-M、Cortex-R、Cortex-A内核,它们的指令集也是不同的,不能通用!

重点区分3个易混概念:
-
ARMv7/ARMv8:架构版本(通用规则说明书)。
-
Cortex-A、Cortex-R、Cortex-M:在通用架构上进行了一定裁剪,形成三种不同产品线。三个类别的指令集不能完全兼容、通用。
-
Cortex-M3/M4/M7:基于通用 Cortex-M 做出的具体CPU内核图纸(虽然都是Cortex-M,但内核硬件架构–如Cache级数、缓存大小等,指令扩展功能不同,性能、功耗等都有一定差异。)
(2)第二层:芯片厂商—做Soc(MCU)
在嵌入式这个对功耗、体积、成本或可靠性有严苛要求的领域,所有厂商都在拥抱这种“集成化”的芯片设计方法,比如汽车电子、工业控制、物联网、智能穿戴等领域,也在广泛使用这类SoC芯片方案,这些领域中的SoC主要是通过Arm公司提供的cPU核心授权来实现。
但ARM公司在行业内的地位太高(整个嵌入式行业的基座)、技术能力要求极高,很少有公司能够直接获得ARM的授权、并制作出对应的Soc。所以这就促进一些中间厂商诞生了,比如ST(意法半导体)、兆易创新(GD32)、NXP、TI这些公司,就是我们常说的MCU厂商。
它们向ARM购买内核IP授权,拿到IP内核图纸后,在CPU核心外部做二次集成开发,形成Soc,并出售给更下游的厂商:
-
给内核搭配片内Flash(存程序)、SRAM(运行内存)
-
添加串口、SPI、ADC、定时器、DMA等外设
-
设计时钟、电源、总线架构
-
最终设计出一颗完整的单片机芯片(STM32、GD32等)
其中,拿Cortex-M核心做出来的Soc被称为MCU,我们要学习的STM32等全都是MCU的具体种类。

且Soc一般只会将存储器、各类片上外设控制器集成到一起,并不会包含各种各样的传感器外设(为了通用性)。于是加入传感器等外设的工作就是下游组装公司的工作了。
(3)第三层:下游组装公司—拿Soc做主板
小米、特斯拉等下游硬件公司拿到 ST、兆易创新产出的 STM32/GD32 这颗完整 MCU 芯片之后,就不再修改芯片内部,而是把这颗 MCU 当作核心元器件,搭配外围电路做成我们看得见的电路板产品。
主要工作内容:
- 将 MCU 芯片焊接在 PCB 电路板上
- 外接电源电路、按键、LED、显示屏、电机、传感器等外设硬件
- 设计电路板走线、接口(USB、串口、CAN 接口等)
- 最后产出开发板、工业控制板、家电主控板等成品硬件
我们拿到的就是如下的产品,这个过程一般是由PCB工程师做出主板,再由嵌入式软件工程师做适配的代码,让产品能正常工作。

二、BOOT引脚与ST-BootLoader刷机原理
(1)什么是启动地址?STM32上电的第一件事
STM32 内核 Cortex‑M3 本身并不知道程序存放在 Flash 里。CPU 上电复位之后,只会去一个固定的起始地址读取第一条指令,这个地址就是程序的入口。
而 STM32 芯片内部有 3 块可以存放代码的区域:
单片机在上电的瞬间,会按照配置从上述的Flash和System ROM中选择一个作为自己的启动地址,进而执行后续代码。
(2)BOOT引脚的作用:选择从哪一块区域启动
所有的机器都不会上电固定从 Flash 启动;上电瞬间,芯片会采样 BOOTx 引脚们的高低电平,根据电平组合,决定CPU 复位后跳转去哪一块存储区域取代码。
在STM32中只有BOOT0和BOOT1,但是在其他的MCU可能有多个BOOT引脚,但他们都只是用来选择启动区域的。
STM32的启动规则如下,且我们一般不会让BOOT1置1,即不会从内存启动:

(3)STM32中的BootLoader是什么?如何刷机的?
ST‑Bootloader(官方出厂 Bootloader) 就是存放在System Memory系统存储器里、ST 工厂固化好的程序。
与imx6uLL等Linux开发板不同,Linux 芯片上电总会先运行片上 ROM 引导代码,再根据 BOOT 设备选择加载 U‑Boot,而STM32的BootLoader只会在BOOT引脚修改到对应模式的时候,才会走BootLoader启动。一般情况下都是直接从Flash跑Startup汇编代码。
-
功能:串口 / USB 刷机下载。当 BOOT 引脚配置成从 System Memory 启动时,芯片就运行它。
-
工作内容:初始化临时的堆栈、硬件寄存器等,然后等待上位机发来固件,收到之后,把程序烧写到 Main‑Flash 里面;烧录完成后,它不会自动运行你的用户程序,需要你断电、修改 BOOT 配置,复位,再从 Flash 启动。
-
⚠️它不执行任何 C 语言环境初始化、不跳转 main 函数。
刷机原理:
很多时候我们可能误操作,在main函数中前几行就关闭了仿真器需要的SWD引脚,当仿真器尝试连接时发现无法建立连接,于是无法重新烧录程序,看起来陷入了自锁状态。有的小白就会担心自己的MCU变成了砖,无法使用了。
其实这就是因为单片机在每次复位后都自动执行到了Flash中的main函数,然后就关闭了SWD调试接口。所以只需要让单片机绕开Flash启动,不进入main函数执行错误代码,问题就迎刃而解了。
联想到刚刚的BootLoader,它进入的是System-ROM,其内部是厂商固化好的一段代码,并不会误操作将SWD引脚关闭。自此我们就既能直接用仿真器烧录程序、还能按照BootLoader的设计,直接用串口进行烧录了。
刷机就是这么简单!
(4)ST-BootLoader与Startup.s启动文件是一个东西吗?
Startup 启动文件是由汇编代码编写、属于用户程序一部分的初始化代码。它的任务:初始化堆栈、配置基本寄存器、建立向量表,最后跳转至 main 函数,为 C 语言程序准备运行环境。
很多人会产生疑问:ST‑Bootloader 运行的时候也初始化过堆栈了,为什么 Startup 还要重新初始化一遍堆栈?
核心原因:二者永远不会在同一次上电流程里先后运行。
因此无论之前有没有运行过 ST‑Bootloader,每次从 Flash 启动时,Startup 都必须重新完成堆栈、运行环境初始化。


