第2章 固件升级基础概念:理解什么是固件、Bootloader、应用程序以及它们之间的关系
各位同学,咱们今天聊点最基础,但也最容易被忽视的东西。
做固件升级,你得先搞清楚三个角色:固件、Bootloader、应用程序。它们仨是什么关系?说白了,就像你家里的三层小楼——地基、一楼、二楼。没有地基,楼就塌了;没有一楼,你上不去二楼;没有二楼,你住哪儿?
2.1 什么是固件?
固件,英文叫 Firmware。我习惯把它理解成「硬件和软件之间的粘合剂」。它不是纯软件,也不是纯硬件,而是固化在非易失性存储器里的程序。
你想想看,一个 MCU 上电后,它怎么知道自己该干什么?它得从 Flash 里读指令。这些指令就是固件。固件里包含了芯片的初始化、外设驱动、中断向量表等等。
我在项目中遇到过一件事:有个同事把固件和应用程序混为一谈,结果升级时只刷了应用层,忘了更新底层驱动,导致新功能死活跑不起来。嗯,这就是没搞清楚固件的边界。
固件的核心特征:
- 存储在 Flash、EEPROM 等非易失介质中
- 掉电不丢失
- 通常包含启动代码、驱动库、运行时环境
- 更新频率低,但一旦更新往往涉及底层改动
2.2 什么是 Bootloader?
Bootloader,直译就是「引导加载程序」。我个人觉得,叫它「看门大爷」更形象——它负责在系统启动时,决定让谁进来、怎么进来。
Bootloader 是 MCU 上电后第一个执行的程序。它的任务很简单:检查条件,然后跳转到应用程序。但就这么简单的任务,里面门道可不少。
我举个例子。你在做 OTA 升级时,Bootloader 要干这些事:
- 检查有没有新固件下载完成
- 如果有,校验完整性(CRC、签名等)
- 把新固件从下载区搬到执行区
- 跳转到新固件执行
如果没有 Bootloader,你想想看,MCU 上电后直接跑应用程序,那你怎么升级?只能通过调试器烧录。这在产线上还行,但远程升级?门儿都没有。
我的经验:Bootloader 的代码要尽量精简。我曾经见过一个 Bootloader 写了 64KB,结果 Flash 不够用,还得压缩应用程序的空间。Bootloader 只做一件事:引导。别往里塞太多功能。
2.3 什么是应用程序?
应用程序,就是用户真正关心的功能代码。比如控制电机、采集传感器数据、通信协议栈等等。它跑在 Bootloader 之上,由 Bootloader 跳转过来执行。
应用程序和 Bootloader 的关系,有点像「老板和前台」。前台(Bootloader)先到公司,开门、开灯、检查设备,然后通知老板(应用程序)可以进来了。老板只管干活,不用管这些杂事。
在 TC3xx 平台上,应用程序通常放在 Flash 的高地址区域。Bootloader 放在低地址区域。为什么?因为 MCU 上电后默认从 0x80000000 开始执行,所以 Bootloader 必须放在那里。
注意:应用程序和 Bootloader 的中断向量表必须分开。应用程序启动时,要重新设置 VTOR 寄存器,指向自己的中断向量表。否则,中断来了,MCU 会跑到 Bootloader 的向量表里去,那就乱套了。
2.4 三者之间的关系
好,咱们把这三个角色串起来看。
| 角色 | 存储位置 | 执行顺序 | 主要职责 |
|---|---|---|---|
| 固件 | Flash 全局 | 贯穿始终 | 提供底层驱动和运行时环境 |
| Bootloader | Flash 低地址 | 第1个执行 | 引导、校验、跳转 |
| 应用程序 | Flash 高地址 | 第2个执行 | 实现用户功能 |
它们之间的关系,我用一句话总结:固件是土壤,Bootloader 是种子,应用程序是长出来的庄稼。
没有固件,芯片连基本的外设都用不了。没有 Bootloader,你没法远程更新庄稼。没有应用程序,你种地干嘛?
2.5 避坑指南
我曾经在项目里踩过一个坑:Bootloader 和应用程序使用了同一个全局变量,结果升级后变量值被覆盖,系统直接死机。后来我学乖了——Bootloader 和应用程序的链接脚本必须严格隔离,共享数据通过固定的 RAM 区域传递,别用全局变量。
还有一点:Bootloader 里不要用复杂的库函数。比如 printf、malloc 这些,能不用就不用。为什么?因为 Bootloader 的代码量要小,越小越稳定。你想想看,Bootloader 出问题了,连升级都做不了,那车就真成砖了。
核心原则:
- Bootloader 只做引导,不做业务
- 应用程序不碰 Bootloader 的 Flash 区域
- 固件升级时,Bootloader 必须保持可执行
- 中断向量表必须独立配置
2.6 小结
这一章的内容,说白了就是让你搞清楚三个角色的分工。很多新手一上来就写应用程序,忽略了 Bootloader 的设计,结果到了 OTA 阶段才发现——根本没法远程升级。
我个人建议,做项目之前,先把这三者的 Flash 分区画清楚。哪块是 Bootloader,哪块是应用程序,哪块是下载区,哪块是备份区。画清楚了,后面的事情就顺了。
下一章,咱们聊聊 TC3xx 的 Flash 架构和分区策略。嗯,那才是真正动手的地方。