当产品需要做封胶处理时,固件的更新必须使用OAD功能。而官方提供了4个示例,到底选哪个呢?

来自豆包的答案:
|---------------------------------------|-------------|---------------------------|-------------------------|----------------------------------|
| 示例名称 | 核心模式 | 依赖组件 | 适用场景 | 优缺点 |
| basic_ble_oad_onchip 适用于【小固件≤30KB)】场景 | 单映像片上 OAD | 需配合 basic_persistent 程序 | 无外部 Flash、对程序大小不敏感的设备 | ✅ 成本低、电路简单 ❌ 需要两次重启、升级停机时间长 |
| basic_ble_oad_dual_image | 双映像片上 OAD | 无需额外程序 | 无外部 Flash、对升级停机时间敏感的设备 | ✅ 一次重启、停机时间短 ❌ 程序最大可用空间受限 |
| basic_ble_oad_offchip | 片外 OAD | 需外部 Flash 芯片 | 有外部 Flash、需要大固件或复杂升级的设备 | ✅ 固件大小无限制、升级过程稳定❌ 增加硬件成本和电路复杂度 |
| basic_ble_multistep_oad | 多步 / 增量 OAD | 片上 / 片外均可,依赖特定协议 | 低功耗、连接不稳定、或需要大固件的设备 | ✅ 支持断点续传、分步升级、容错性强 ❌ 协议更复杂,调试难度高 |
就从新手入门难易度来说主要考虑"basic_ble_oad_onchip"和"basic_ble_oad_dual_image"两种。
一、"basic_ble_oad_onchip" OAD机制解释
basic_ble_oad_onchip 是单映像片上 OAD ,它的核心是「用户应用 + Persistent 程序 + MCUBoot」三段式设计,需要依赖 basic_persistent 程序完成固件搬运。
CC2340 512KB Flash On-Chip OAD 标准分区(SDK 默认):
|----------------------------|--------------------------------|-------|---------------------------------------------------|
| 区域 | 地址范围 | 大小 | 作用 |
| MCUBoot Bootloader | 0x00000000 ~ 0x000006000 | 24KB | 设备上电后首先运行,负责校验固件、决定启动哪个程序 |
| Persistent App | 0x000006000 ~ 0x000032000 | 176KB | 固件搬运程序,下载新固件后,MCUBoot 会先跳转到这里执行 |
| User App 运行区(Primary Slot) | 0x000032000 ~ 0x00006B000 | 220KB | 当前正在运行的用户应用(你自己的业务代码) MCUboot App中的起始地址和大小需要与该区相同 |
| OAD 下载缓冲区(Secondary Slot) | 0x00006B000 ~ 0x00007D000 | 72KB | 新固件下载的临时存储区 开辟的空间需要大于你的固件大小 |
| NVS(蓝牙配置数据区) | 0x00007D000 ~ 0x000080000 | 12KB | 存储配对信息、用户配置等掉电不丢的数据 |
二、"basic_ble_oad_onchip" OAD烧录方法
1)烧录程序时需要烧录支持OAD升级的相关引导程序。
mcuboot_onchip_LP_EM_CC2340R5_nortos_ticlang.hex****;**** (来源:C:\ti\simplelink_lowpower_f3_sdk_9_20_00_81\examples\rtos\LP_EM_CC2340R5\ble\prebuilt_hexfiles)
basic_persistent_LP_EM_CC2340R5_freertos_ticlang.bin****;**** (来源:对C:\ti\simplelink_lowpower_f3_sdk_9_20_00_81\examples\rtos\LP_EM_CC2340R5\ble\basic_persistent工程重新编译生成)
basic_ble_oad_onchip_LP_EM_CC2340R5_freertos_ticlang_v1.bin****;**** (来源:你工程项目Release文件夹下生成的二进制文件)
备注:
· basic_ble_oad_onchip_LP_EM_CC2340R5_freertos_ticlang.hex日常调试用,不支持OAD功能。
· basic_ble_oad_onchip_LP_EM_CC2340R5_freertos_ticlang_v1.bin要实现OAD功能时烧录程序使用v1.bin文件
· basic_ble_oad_onchip_LP_EM_CC2340R5_freertos_ticlang_v2.bin为App(Simplelink Connect_1.3.4)更新固件用
2)UniFlash烧录程序,如下图所示,主要注意事项就是地址的填写:

3)Simplelink Connect_1.3.4打开v2.bin实现更新升级。
三、"basic_ble_oad_onchip"OAD的坑
实际烧录时各种提示超界!512Flash不够用!!!它适用于【小固件(≤30KB)】场景,比如简单传感器、按键、LED 控制、小功耗设备,对 极低成本、极小代码、不需要大空间 的设备有用!!
项目生成的bin文档约187KB,为了保存历史数据需要30-40KB的NVS数据空间。
按照"basic_ble_oad_onchip "的分配机制:
|----------------------------|---------|---------------------|
| MCUBoot Bootloader | 24KB | (固定大小) |
| Persistent App | 176KB | (固定大小) |
| User App 运行区(Primary Slot) | 187KB的bin安全开辟200-220KB空间,假设200KB ||
| OAD 下载缓冲区(Secondary Slot) | 缓冲区必须要大于你的固件,假设200KB ||
| NVS(必须的蓝牙配置区) | Min:4KB | 存储配对信息、用户配置等掉电不丢的数据 |
以上已经需要:644KB,512Flash已经不够用了。
固件大于30KB的项目不要使用basic_ble_oad_onchip 例程!
四、"basic_ble_oad_dual_image" OAD机制解释
basic_ble_oad_dual_image是双映像 A/B 分区,Flash 被分成「运行区 A + 备份区 B」,MCUBoot 直接在两个完整固件间切换。
CC2340 512KB Flash oad_dual_image OAD 标准分区(SDK 默认):
|----------------|---------|---------------|---------|
| 默认配置 ||||
| 分区 | Start | Size | End |
| MCU Bootloader | 0x0 | 0x6000(24K) | 0x6000 |
| 芯片上电后第一个执行的程序,负责: * 硬件初始化(时钟、Flash、GPIO 等) * 判断当前要启动哪个镜像(A/B 槽) * 支持 OAD 时的镜像校验、跳转 TI 的 BLE 双镜像 Bootloader 代码本身需要约 16~20KB,预留 24KB 是安全冗余。 这个分区只读、不被 OAD 覆盖,是设备的 "救命稻草",就算所有应用镜像都坏了,Bootloader 还在,能进串口 / OTA 恢复模式。 ||||
| A | 0x6000 | 0x3D000(244K) | 0x43000 |
| · 作用 : 主应用镜像(Active Image) * 设备当前运行的 BLE 应用程序就放在这里。 * 当没有新镜像时,Bootloader 直接从这里启动。 · 大小 244KB : * 244KB 是 0x43000 - 0x6000 = 0x3D000,换算为十进制是 245,760 字节(240KB 级),足够放下一个完整的 BLE 应用 + 协议栈 + OAD 驱动。 ||||
| B(OAD下载槽) | 0x43000 | 0x3D000(244K) | 0x80000 |
| · 作用 : 备用镜像槽(Update Image) * 这是双镜像 OAD 的核心设计: 1. 新的固件先通过 BLE 下载到 B 分区,不会覆盖正在运行的 A 分区。 2. 下载完成后,Bootloader 会校验 B 分区的镜像完整性和签名。 3. 校验通过后,下次重启就从 B 分区启动,此时 B 分区变成新的主镜像。 4. 再次 OAD 时,又会把新固件下载到现在空闲的 A 分区,实现循环更新。 · 为什么和 A 分区一样大 : * 必须保证两个镜像槽大小相同,这样 Bootloader 才能无差别地加载和跳转,不会因为镜像大小超出分区边界而导致启动失败。 ||||
| NVS | 0x7D000 | 0x3000(12K) | 0x80000 |
| · 作用 :非易失性存储(Non-Volatile Storage) * 用来存断电后需要保留的数据,比如: * BLE 绑定信息、配对密钥 * 设备配置参数(广播间隔、连接参数) * OAD 状态标志(当前哪个镜像有效、更新进度) · 为什么放在最后 12KB : * 放在 Flash 尾部是行业惯例,这样前面的应用镜像和 Bootloader 都不会意外覆盖到它。 * 12KB 大小足够存放大量键值对数据,且 Flash 擦除通常按 4KB 或 8KB 扇区操作,12KB 刚好是 3 个 4KB 扇区,擦除效率高。 * 地址必须在 Flash 最尾部 , 可以改大小 , 最小 4KB,最大随便你(16KB、20KB 都可以但必须是4K的倍数) , 只要尾部位置不变,OAD 永远正常 ||||
| NVS1 | 0x41000 | 0x3B000(236K) | 0x7C000 |
| OAD | 0x41000 | 0x3B000(236K) | |
| · 这两个其实是同一个物理区域,只是用途不同 : * OAD 视角 :0x41000 ~ 0x7C000 是 B 分区里的一部分,作为OAD 下载缓存区 ,用来存放正在下载的固件分片。 * NVS 视角 :这个地址范围在一些配置里也可以被当作 NVS1 分区,用来存更大的数据集,不过在你这个 basic_ble_oad_dual_image 工程里,它主要是 B 分区的一部分。 · 注意 :你表里的 NVS1 分区和 B 分区的地址范围有部分重叠(0x43000 ~ 0x7C000),这是因为: * 0x41000 ~ 0x43000 这 8KB 是 A 分区的尾部,也可以被配置为 NVS,用来存 A 镜像的状态信息。 * 实际运行时,Bootloader 会通过地址范围判断当前是哪个镜像在运行,只会操作对应镜像的 NVS 区域,不会冲突。 * B 镜像总长 244KB-B 镜像前 8KB 存镜像头部 =236KB 它是 OAD 升级时的固件下载缓存区,其实就是B 镜像区本身。 可以调整大小,只要满足:NVS1/OAD 空间 <= B 镜像大小 * A 和 B 镜像大小必须对称 若是B 镜像缩到 224KB,那 NVS1/OAD 自动变成 216KB~220KB 都可以。 为什么它的地址和镜像A和镜像B都有重叠呢? 不是真的重叠,而是 TI 的一种 "地址复用" 的标记方式,本质是 1. NVS1/OAD 根本不是独立分区 它只是 B 镜像区的一个别名 ,只在 Bootloader 下载固件时 才被当作 "下载缓存区"。 * 当设备从 A 镜像启动 时,0x041000~0x043000 这一段是 A 镜像的尾部代码 ,NVS1 完全不用。 * 当设备从 B 镜像启动 时,0x041000~0x043000 这一段是 B 镜像的头部 ,同样不会被当作 NVS 使用。 2. 真正的 "重叠" 只存在于配置文件的标记里,运行时不会冲突 Bootloader 会根据当前启动的镜像,自动忽略另一部分地址: * 运行 A 镜像时,只会把 B 镜像区(0x043000~0x080000)当作 OAD 下载区。 * 运行 B 镜像时,只会把 A 镜像区当作旧版本,不会去擦写它。 所以默认配置里的 "重叠",是一种逻辑上的复用标记 ,不是物理上的地址冲突。 ||||
| 优缺点: ✅ 优点 * 结构清晰,双镜像槽完全对称,Bootloader 逻辑简单稳定。 * NVS 放在尾部,不会被应用镜像意外覆盖。 * 244KB 的镜像空间足够放下大部分 BLE 应用。 ⚠️ 注意事项(你可能会遇到的坑) 1. A/B 分区的地址边界不能改 * 如果你想增大应用镜像的大小,必须同时修改 A 和 B 分区的大小,保持两者一致,否则 Bootloader 会校验失败。 2. NVS 分区不能被应用代码占用 * 编译时要确保你的应用代码的链接脚本(.cmd 文件)里,text 和 rodata 段的结束地址不能超过 0x7D000,否则会覆盖 NVS 数据。 3. Bootloader 分区不能动 * 绝对不要修改 0x0 ~ 0x6000 的内容,否则设备会直接变砖,需要用仿真器重新烧写 Bootloader。 ||||
五、"basic_ble_oad_dual_image"OAD烧录方法
1)烧录程序时需要烧录支持OAD升级的相关引导程序。
mcuboot_dual_image_LP_EM_CC2340R5_nortos_ticlang.hex****;**** (来源:C:\ti\simplelink_lowpower_f3_sdk_9_20_00_81\examples\rtos\LP_EM_CC2340R5\ble\prebuilt_hexfiles)
basic_ble_oad_dual_image_LP_EM_CC2340R5_freertos_ticlang_v1.bin****;**** (来源:你工程项目Release文件夹下生成的二进制文件)
备注:
· basic_ble_oad_dual_image_LP_EM_CC2340R5_freertos_ticlang.hex日常调试用,不支持OAD功能。
· basic_ble_oad_dual_image_LP_EM_CC2340R5_freertos_ticlang_v1.bin要实现OAD功能时烧录程序使用v1.bin文件
· basic_ble_oad_dual_image_LP_EM_CC2340R5_freertos_ticlang_v2.bin为App(Simplelink Connect_1.3.4)更新固件用
2)UniFlash烧录程序,如下图所示,主要注意事项就是地址的填写:

3)Simplelink Connect_1.3.4打开v2.bin实现更新升级。
六、"basic_ble_oad_dual_image"OAD的坑
用Simplelink Connect更新固件时,一直卡在了Proccess 0%上,程序能正常运行,但就是不能OAD更新固件。最终确认原因为Flash空间分配错误!
|----------------|---------|---------------|---------|
| 重新分配 ||||
| 分区 | Start | Size | End |
| MCU Bootloader | 0x0 | 0x6000(24K) | 0x6000 |
| A | 0x6000 | 0x38000(224K) | 0x3E000 |
| B(OAD下载槽) | 0x3E000 | 0x38000(224K) | 0x76000 |
| NVS1/OAD | 0x3F000 | 0x36000(216K) | 0x75000 |
| UserNVS | 0x76000 | 0x8000(32K) | 0x7E000 |
| NVS | 0x7E000 | 0x2000(8K) | 0x80000 |