1. 分区概念入门:什么是分区表、为什么需要分区、分区在嵌入式系统中的角色

各位同学,咱们今天聊点实在的。分区这个概念,说白了就是把一块存储空间划分成几个独立的小房间。每个房间有各自的用途,互不干扰。我刚开始做嵌入式那会儿,也觉得分区挺麻烦的——直接往 Flash 里写数据不就行了?后来踩了坑才明白,没有分区,你的系统就像没有隔间的出租屋,乱成一锅粥。

1.1 什么是分区表

分区表,就是一张「地图」。它告诉系统:你的 Flash 芯片里,哪一段存 Bootloader,哪一段存固件,哪一段存配置参数。没有这张地图,CPU 上电后根本不知道该从哪里开始跑代码。

分区表的核心信息:

  • 名称:分区的标识,比如 boot、app、config
  • 起始地址:该分区在 Flash 中的偏移量
  • 大小:分区占用的字节数
  • 类型:app(可执行)、data(数据存储)、factory(出厂备份)

举个例子,一个典型的 ESP32 分区表长这样:

# ESP32 Partition Table
# Name,   Type, SubType, Offset,  Size,   Flags
nvs,      data, nvs,     0x9000,  0x5000,
otadata,  data, ota,     0xe000,  0x2000,
app0,     app,  ota_0,   0x10000, 0x1F0000,
app1,     app,  ota_1,   0x200000,0x1F0000,

你看,每一行就是一个分区。系统启动时,Bootloader 会读取这张表,然后跳转到 app0 或 app1 去执行。嗯,这里要注意:分区表的起始地址通常是固定的,比如 ESP32 默认放在 0x8000 位置。如果你不小心把分区表擦掉了,整个系统就变砖了——我当年就干过这种事,焊了三次 Flash 才救回来。

1.2 为什么需要分区

你可能会问:我把所有代码和配置都塞在一个连续区域里,不也能跑吗?

能跑,但风险很大。我给你列几个场景:

场景 不分区的后果 分区后的好处
OTA 升级失败 固件写一半断电,系统彻底变砖 保留一个备份分区,回滚到旧版本
配置参数被误改 擦除整个 Flash,固件也没了 配置分区独立,擦除不影响代码
多固件共存 无法同时存放两个版本 app0 和 app1 各占一块,互不干扰
安全隔离 用户程序可以随意访问 Bootloader 硬件分区保护,防止越权读写

说白了,分区就是给系统上了几道保险。我做过一个智能家居网关的项目,客户要求支持远程升级。当时我设计了三个分区:Bootloader、App 主区、App 备份区。有一次升级过程中网络断了,设备重启后自动从备份区启动,用户甚至没感觉到异常。这就是分区的价值。

1.3 分区在嵌入式系统中的角色

分区在嵌入式系统里,扮演着三个关键角色:

1.3.1 启动引导者

系统上电后,CPU 从复位向量指向的地址开始执行。这个地址通常就是 Bootloader 分区的起始位置。Bootloader 读取分区表,找到可用的 App 分区,然后跳转过去。整个过程就像接力赛——分区表就是交接棒的位置。

我的经验:Bootloader 分区一定要放在 Flash 的最开头,而且大小要留足。有些芯片的启动 ROM 只认前 64KB,你放大了它读不到,放小了功能不够用。我一般会留 128KB 给 Bootloader,多出来的空间存一些出厂测试代码。

1.3.2 数据隔离者

嵌入式系统里,不同类型的数据有不同的生命周期:

  • 固件代码:只读,升级时才写入
  • 运行参数:频繁读写,比如 Wi-Fi 密码、传感器校准值
  • 日志记录:循环写入,需要磨损均衡
  • 文件系统:需要随机访问,比如存储图片或配置文件

如果不分区,这些数据混在一起,擦写次数会快速耗尽 Flash 的寿命。分区之后,你可以为每个区域设置不同的擦写策略。比如参数分区用高耐久度的 NVS(非易失性存储),日志分区用 SPIFFS 或 LittleFS 文件系统。

1.3.3 安全守护者

现代嵌入式芯片大多支持硬件分区保护。你可以给 Bootloader 分区设置「只读」属性,防止用户程序意外擦除。有些芯片甚至支持加密分区——固件在 Flash 里是密文,运行时才解密。

我曾经踩过的坑:有一次做量产工具,没注意分区表里 Bootloader 的起始地址写错了,结果烧录了 1000 台设备全部无法启动。后来排查发现,分区表偏移量少算了 4 个字节。从那以后,我每次写分区表都会用十六进制编辑器逐字节核对。别嫌麻烦,这种错误查一次就够你受的。

1.4 分区结构图

下面这张图展示了一个典型的嵌入式系统分区布局。你可以看到,Flash 从低地址到高地址,依次排列着 Bootloader、分区表、多个 App 分区和数据分区。

嵌入式 Flash 分区布局示意图 Flash 芯片(如 4MB / 8MB / 16MB) 0x000000 0x008000 0x010000 0x200000 0x3F0000 Bootloader 分区(32KB) 分区表(4KB) App 主分区(app0) 约 1.9MB App 备份分区(app1) 约 1.9MB 数据分区(NVS / 文件系统 / 日志) 启动流程: Bootloader → 分区表 → App

你看,Bootloader 在最前面,紧接着是分区表。App 主分区和备份分区大小相同,这样 OTA 升级时可以无缝切换。最后面的数据分区留给运行时数据。这个布局是我在多个项目中验证过的,稳定可靠。

1.5 小结

分区不是什么高深的技术,但它决定了嵌入式系统的健壮性。记住三点:

  • 分区表是系统的地图,没有它,CPU 找不到代码
  • 分区实现了隔离,固件、配置、日志各归其位
  • 分区支持了 OTA,备份分区让你敢升级、不怕失败