这一篇是整个嵌入式系统中最“神秘”的阶段。大多数工程师写代码时只关注 main() 里的逻辑,却很少有人去翻看那几百行汇编启动代码。
然而,90% 的“上电死机”、“变量初值错误”和“看门狗复位循环”,根源都在这里。
入式内存深究(3):苏醒的时刻 —— 启动与初始化
1. 引言:Main 函数之前的“真空期”
初学者往往认为:单片机上电复位后,第一行执行的代码就是 main() 函数的第一行。 大错特错。
从 CPU 复位(Reset)到 main() 函数入口,中间有一段长达数毫秒甚至数十毫秒的**“真空期”**。这段时间里,CPU 在狂奔,但你的业务代码还没开始跑。这段代码通常被称为 Startup Code (启动代码) 或 CRT (C Runtime Initialization)。
它的核心任务只有一个:把静态的 Flash 变成了动态的 RAM。
2. 核心任务:Scatter Loading (分散加载)
为什么需要启动代码?因为 C 语言标准规定:
-
全局变量必须有初值:
int a = 10;在进入 main 前必须已经是 10。 -
未初始化变量必须为 0:
int b;在进入 main 前必须已经是 0。
但物理现实是:
-
Flash 是非易失的,存了初值
10,但它是只读的(Read-Only)。 -
RAM 是易失的,上电时里面全是随机的乱码(Random Garbage)。
因此,启动代码必须扮演“搬运工”的角色:
-
Copy: 把
.data段的初值从 Flash 搬运到 RAM。 -
Zero: 把
.bss段所在的 RAM 区域全部填 0。
3. STM32G0 实战:优雅的标准流程
Cortex-M 的启动流程是高度标准化的。我们以 Keil MDK (ARMCC) 或 GCC 为例,剖析 startup_stm32g0xx.s。

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



