00-bootloader前置知识
2026/5/20大约 5 分钟
00-bootloader前置知识
编译优化
-O0:零优化(刚入职的实习生)
- 它的行为:绝对听话,极其死板。你 C 语言怎么写,它就一行一行怎么翻译成汇编。你定义了一个变量,它就老老实实去内存(栈)里开辟空间,哪怕这个变量只用了一次。
- 优点:调试的绝对王者。因为代码是 1:1 翻译的,你在打断点、单步调试、查看局部变量时,一切都完美对应,绝不会出现“变量被优化掉”或者“断点乱跳”的情况。
- 缺点:生成的 Bin 文件极其巨大,运行速度最慢。
- 适用场景:日常开发和 Debug 阶段。
-O1:基本优化(熟练的产线工人)
- 它的行为:开始动脑子了。它会把一些明显的废话(永远执行不到的死代码)删掉;更重要的是,它开始大量使用 CPU 的寄存器来保存局部变量,而不是每次都慢吞吞地去读写内存(栈)。
- 优点:代码体积开始缩小,运行速度明显提升。同时,它保留了基本的调试能力。
- 缺点:比上不足,比下有余。
- 适用场景:既想代码跑得快一点,又需要偶尔 Debug 的中间状态。
-O2:标准高级优化(车间主任)—— 工业界的最爱
- 它的行为:编译器彻底放飞自我。它会进行指令重排(打乱你写代码的顺序,以迎合 CPU 的流水线)、常量折叠(把你写的
3 * 24 * 60编译时直接算成4320填进去)。只要它觉得怎么执行快,它就怎么改你的逻辑(但保证最终结果一样)。 - 优点:运行速度极快,同时体积控制得也不错。
- 缺点:Debug 的噩梦。如果你在 O2 下单步调试,你会发现断点在代码行之间上下横跳,局部变量全部显示
<optimized out>(被优化掉了,没放进内存)。 - 适用场景:产品 Release(发布)时的默认标准。
-O3:性能狂魔(疯狂的科学家)
- 它的行为:为了极致的运行速度,可以牺牲一切(包括代码体积)。它会干两件疯狂的事:
- 函数内联(Inlining):把你写的小函数,直接像宏定义一样复制粘贴到调用的地方,省去了函数调用的跳转开销,但代码体积会膨胀。
- 循环展开(Loop Unrolling):把你写的
for(i=0; i<4; i++) { do_something(); },直接强行展开成 4 句do_something();,省去了i++和条件判断的时间。
- 优点:单片机能跑出的最高执行速度。
- 缺点:Bin 文件体积显著膨胀(空间换时间)。
- 适用场景:需要跑极其复杂的算法(如电机 FOC 控制、DSP 音频处理、FFT 运算)的专属核心代码段。
-Ofast:法外狂徒(不要命的赛车手)
- 它的行为:在
-O3的基础上,打破 C 语言和 IEEE 国际标准。特别是针对浮点数(float/double)运算,它会为了速度忽略所有安全检查(比如不管非法的NaN和无限大Inf,强行改变数学运算的结合律)。 - 优点:浮点数数学运算快到起飞。
- 缺点:极度危险。如果你的数学公式里有可能出现除以 0 或者溢出,程序会跑出诡异的结果。
- 适用场景:纯粹的数字信号处理,且你 100% 确保输入数据是合法的。
🌟 终极省空间绝招:大小之争
对于我们写 Bootloader 来说,速度根本不重要(跳转就那几微秒),体积才是王道。这时候就要用到针对体积的优化:
-Os:空间魔术师(精打细算的管家)
- 它的行为:启用所有
-O2级别的优化,但坚决拒绝任何会增加代码体积的优化行为(比如它绝对不会像 O3 那样去展开循环或者内联大函数)。 - 优点:在保持较高运行速度的同时,尽可能缩小 Bin 文件体积。
- 适用场景:Flash 空间比较紧张的常规 App 工程。
-Oz / -Omax:黑洞级压缩(榨干最后一滴血)
(注:-Oz 是 Keil AC6 / Clang 编译器专属的极致空间优化;-Omax 通常是 Keil GUI 里的叫法,代表开启了 LTO 跨模块优化的极限状态)
- 它的行为:为了缩小体积,可以牺牲运行速度。它会把所有长得差不多的代码段,强行提取成一个公共函数供大家调用(哪怕跳转会浪费一点时间)。它会用一切极其晦涩、短小的汇编指令来替代常规指令。
- 优点:单片机界最小的 Bin 文件,没有之一。
- 缺点:代码执行速度会变慢,且绝对无法 Debug。
- 适用场景:你的 Bootloader! 因为 Bootloader 的专属 Flash 扇区往往只有 8KB 到 16KB,必须用
-Oz把它压到极致
总结
| 优化等级 | 核心目标 | 体积 (Size) | 速度 (Speed) | 调试难度 | 一句话总结 |
|---|---|---|---|---|---|
| -O0 | 方便调试 | 极大 | 最慢 | ⭐ (极易) | 开发阶段的保姆 |
| -O1 | 均衡过渡 | 中等 | 中等 | ⭐⭐ | 稍微聪明的保姆 |
| -O2 | 全局均衡 | 较小 | 极快 | ⭐⭐⭐⭐ | 工业发布的标准 |
| -O3 | 空间换时间 | 膨胀 | 神速 | ⭐⭐⭐⭐⭐ | 算法狂魔的最爱 |
| -Os | 兼顾体积 | 很小 | 较快 | ⭐⭐⭐⭐ | Flash 告急时的救星 |
| -Oz | 时间换空间 | 极小 | 较慢 | ⭐⭐⭐⭐⭐ (地狱) | Bootloader 专属榨汁机 |
- o0:零优化,生成的 Bin 文件极其巨大,运行速度最慢,用于日常开发和 Debug 阶段。
- o1:基础优化,既想代码跑得快一点,又需要偶尔 Debug 的中间状态,不建议使用。
- o2:打乱你写代码的顺序,以迎合 CPU 的流水线、把你写的
3 * 24 * 60编译时直接算成4320填进去。只要它觉得怎么执行快,它就怎么改你的逻辑,运行速度极快,同时体积控制得也不错,但是无法Debug。 - o3:为了极致的运行速度,可以牺牲一切(包括代码体积),不能debug,不要用于Bootloader。
- ofast:在
-O3的基础上,打破 C 语言和 IEEE 国际标准,运行时可能会出现错误,但是浮点数数学运算快到起飞。 - oz/omax:为了缩小体积,可以牺牲运行速度,无法Debug,但是体积小,适用于Bootloader。