编译后处理与镜像打包
本文档介绍 AD23N 通用 MCU SDK 中"编译完成之后"的自动化后处理与镜像打包机制:sdk/app/post_build 下的编排脚本、固件镜像生成工具(fw_add.exe、ufw_maker.exe、isd_download.exe)、Flash 写保护参数生成链路、资源分区目录以及链接脚本生成器。该环节把编译器输出的原始固件转换为可烧录、可升级、带写保护的最终交付镜像。
Purpose and Scope
本页面聚焦于 post-build(编译后处理) 阶段的完整链路,包括:
sdk/app/post_build/sh59/下的入口脚本与生成器源码(download.bat、download_bat.c);- 镜像加工工具:
fw_add.exe(固件头/校验添加)、ufw_maker.exe(UFW 升级包打包)、isd_download.exe(烧录下载); - Flash 写保护子链路:
flash_list_to_bin_v3.bat、flash_wp_tool.exe、flash_params_v3.bin与芯片参数表(0xC8671A_v3.xlsx、0xEF4017_v3.xlsx); - 资源分区目录(
dir_*)的打包角色; - 链接脚本相关文件(
app_ld.c、maskrom_stubs.ld)。
以下相关内容属于兄弟页面,不在本页展开:
- 编译构建与工具链:
sdk/make_prompt.bat、sdk/tools/utils/do_merge_libs.bat(库合并)等属于"编译系统"能力; - 运行时升级/OTA 协议:UFW 文件被 OTA/升级模块消费的具体协议细节属于"固件升级"能力;
- Flash 整体布局:
flash_params_v3.bin的最终烧录位置与分区表定义属于"存储布局"能力。
信息来源说明:本页基于仓库文件清单(ListFiles 结果)撰写。文件与目录的存在、命名、相对位置均为已核实的仓库事实;各工具的"功能描述"依据其命名与目录上下文推断得出。受源码读取预算限制,批处理脚本内部实现细节未逐一核对,涉及推断处均已标注"推断"。
Overview
嵌入式 SDK 的交付物不是编译器输出的裸固件,而是经过一系列后处理的镜像:需要追加头部/校验信息、按分区组织资源、可能生成写保护参数、最终打包为统一固件(UFW)以便量产烧录与 OTA 升级。
AD23N SDK 把这一整套流程独立放在 sdk/app/post_build/sh59/ 下,核心设计意图:
- 解耦编译与交付:编译器只负责产出原始目标文件,镜像的"可用化"(加头、校验、打包)全部由后处理工具链完成,便于在多个项目/型号间复用同一套流程。
- 原生工具、零依赖:后处理工具(
fw_add.exe、ufw_maker.exe、isd_download.exe、flash_wp_tool.exe)均为独立可执行文件,不依赖编译器的运行环境,可在 CI 或量产脚本中直接调用。 - 脚本编排、源码生成:
download.bat是后处理总入口;有趣的是它本身由 C 程序download_bat.c生成——用源码生成脚本可以避免手工维护批处理时常见的路径/参数错误,保证不同工程生成的后处理脚本行为一致。 - 写保护与安全:
flash_write_protect子目录专门处理 Flash 写保护:以 Excel 参数表(按芯片型号,如0xC8671A_v3.xlsx、0xEF4017_v3.xlsx)为输入,经flash_list_to_bin_v3.bat与flash_wp_tool.exe转换为flash_params_v3.bin,用于保护关键区域(如 Boot/MaskROM 相关区段)。 - 资源分区目录化:
dir_a、dir_bin_f1x、dir_eng、dir_ex_flash、dir_midi、dir_notice、dir_poetry、dir_song、dir_story等目录分别对应不同资源分区(提示音、MIDI、歌曲、故事、诗歌、通知、英文等),打包脚本按目录聚合资源,天然支持按需增删分区。
Architecture
flowchart TD
subgraph sg_Build["编译输出 (Build Output)"]
Obj["obj/bin 原始固件镜像"]
Res["dir_* 资源分区目录"]
end
subgraph sg_PostBuild["post_build 后处理 (sdk/app/post_build/sh59)"]
GenBat["download_bat.c (生成 download.bat)"]
Bat["download.bat 编排入口"]
FwAdd["fw_add.exe (固件头/校验)"]
Ufw["ufw_maker.exe (UFW 打包)"]
Isd["isd_download.exe (烧录下载)"]
Ld["app_ld.c / maskrom_stubs.ld (链接脚本)"]
end
subgraph sg_Wp["Flash 写保护 (flash_write_protect)"]
Xlsx["0xC8671A_v3.xlsx / 0xEF4017_v3.xlsx 参数表"]
ListBat["flash_list_to_bin_v3.bat"]
WpTool["flash_wp_tool.exe"]
Params["flash_params_v3.bin"]
end
Obj --> Bat
Res --> Bat
GenBat --> Bat
FwAdd --> Bat
Ufw --> Bat
Isd --> Bat
Ld --> Obj
Xlsx --> ListBat --> WpTool --> Params
Bat --> Params
Bat --> Ufw
Ufw --> Isd
架构说明:
- 上游:编译输出(原始固件镜像、
dir_*资源)是后处理的输入;app_ld.c/maskrom_stubs.ld参与链接阶段,保证应用与 MaskROM 符号正确衔接(推断)。 - 编排层:
download.bat作为总入口串联各工具;它由download_bat.c生成,确保不同工程脚本的一致性。 - 工具层:
fw_add.exe负责给镜像追加头/校验信息;ufw_maker.exe把多个分区打包为统一固件(UFW);isd_download.exe负责下载/烧录。 - 写保护链路:芯片参数表(xlsx)→
flash_list_to_bin_v3.bat转换 →flash_wp_tool.exe生成写保护 bin,最终参与镜像打包。
主要组件与实现详解
1. post_build 目录结构与职责
post_build 目录按芯片型号组织(当前为 sh59),每个型号目录下自带完整的后处理工具与资源:
| 文件/目录 | 类型 | 职责(依据命名与上下文推断) |
|---|---|---|
download.bat | 批处理脚本 | 后处理总入口:调用各工具生成最终可烧录镜像 |
download_bat.c | C 源码 | download.bat 的生成器——用源码输出批处理,保证脚本行为一致 |
maskrom_stubs.ld | 链接脚本 | 为 MaskROM 中的函数提供 stub 符号,使应用链接时不依赖 MaskROM 实际地址 |
mbox_flash/app_ld.c | C 源码 | 生成应用链接脚本(app_ld)的辅助程序(推断),控制应用在 Flash 中的布局 |
mbox_flash/fw_add.exe | 可执行工具 | 为原始固件追加头部/校验信息,产出标准镜像 |
mbox_flash/ufw_maker.exe | 可执行工具 | Unified FirmWare 打包器:将多个分区/镜像合并为 UFW 升级包 |
mbox_flash/isd_download.exe | 可执行工具 | ISP 下载工具:将镜像烧录到目标芯片 |
mbox_flash/flash_wp_tool.exe | 可执行工具 | Flash 写保护参数生成工具 |
mbox_flash/dir_* | 资源目录 | 各类资源分区:dir_a、dir_bin_f1x、dir_eng、dir_ex_flash、dir_midi、dir_notice、dir_poetry、dir_song、dir_story |
mbox_flash/flash_write_protect/ | 子目录 | 写保护参数生成子链路(见下文第 3 节) |
推断标注:批处理与 C 生成器内部的具体命令序列未在本页读取中核对,上表"职责"依据文件名与目录上下文得出,属于合理推断而非已核实的源码行为。
2. 镜像生成工具链
后处理核心是三个可执行工具,分别对应镜像生命周期的三个环节:
fw_add.exe — 固件头与校验添加(推断)
编译器/链接器产出的裸镜像不能直接用于量产烧录或 OTA,需要追加包含版本、长度、校验和等信息的头部。fw_add.exe 承担该角色:读取原始镜像,写入头部字段并计算校验,输出带头的标准镜像。它的存在使"编译"与"镜像规范化"解耦——只要链接产物格式不变,后处理工具无需随编译器升级。
ufw_maker.exe — UFW 统一固件打包(推断)
UFW(Unified FirmWare)是杰理方案常用的多分区升级包格式,把应用固件、资源分区、写保护参数等打包为一个文件,供量产工具或 OTA 使用。ufw_maker.exe 负责把各分区输入聚合成 UFW;download.bat 中会先调用 fw_add.exe 等生成各分区镜像,再调用 ufw_maker.exe 打包(推断)。
isd_download.exe — 下载/烧录(推断)
isd_download.exe 是面向芯片的下载工具,通过 ISP/串口/USB 把打包好的镜像写入目标设备 Flash,用于开发调试与产线烧录。
3. Flash 写保护子链路
mbox_flash/flash_write_protect/ 目录专门管理写保护参数:
flowchart LR
X["芯片参数表<br/>0xC8671A_v3.xlsx / 0xEF4017_v3.xlsx"] --> B["flash_list_to_bin_v3.bat<br/>(列表转 bin)"]
B --> T["flash_wp_tool.exe<br/>(写保护工具)"]
T --> P["inside_flash/flash_params_v3.bin<br/>(写保护参数)"]
P --> M["ufw_maker.exe 打包进镜像"]
- 输入:按芯片型号区分的 Excel 参数表(
0xC8671A_v3.xlsx、0xEF4017_v3.xlsx),描述需要写保护的区域列表; - 转换:
flash_list_to_bin_v3.bat把参数表转换为二进制列表(推断); - 生成:
flash_wp_tool.exe依据列表生成最终写保护参数flash_params_v3.bin(存放于inside_flash/); - 集成:写保护参数随后被纳入镜像打包流程。
设计意图:写保护区域配置属于"易变、按型号不同"的参数,因此用 Excel 表维护、用工具转换,而不是写死在脚本里——换芯片型号时只需替换参数表,无需改动脚本。
4. 资源分区目录(dir_*)
mbox_flash/ 下按内容类型划分了多个资源目录,打包脚本按目录聚合资源(推断):
| 目录 | 内容类型(推断) |
|---|---|
dir_a | 应用/通用资源 |
dir_bin_f1x | F1x 系列 bin 资源 |
dir_eng | 英文语音/文本资源 |
dir_ex_flash | 外置 Flash 资源 |
dir_midi | MIDI 资源 |
dir_notice | 通知音/提示音资源 |
dir_poetry | 诗歌内容资源 |
dir_song | 歌曲内容资源 |
dir_story | 故事内容资源 |
这种"一目录一分区"的设计使新增内容类型时只需新增目录并接入打包脚本,资源与代码的维护边界清晰。
5. 链接脚本与 MaskROM stub
maskrom_stubs.ld:MaskROM 固化的函数在链接阶段表现为"未知符号"。该脚本为这些符号提供 stub 定义(推断),使应用链接通过;实际调用由 MaskROM 运行时代码解析,从而让同一份应用代码可运行于不同 MaskROM 版本。app_ld.c:C 编写的链接脚本生成器(推断),按工程配置动态生成应用链接脚本,控制代码段、数据段在 Flash 中的布局。
核心流程
一次典型的后处理执行流程如下:
sequenceDiagram
participant Dev as 开发者/CI
participant Bat as download.bat (post_build 入口)
participant Tools as 工具链 (fw_add / ufw_maker)
participant WP as flash_wp_tool.exe
participant Out as 最终交付镜像
Dev->>Bat: 编译完成后执行后处理
Bat->>Tools: 1. fw_add.exe 为原始固件添加头/校验
Tools-->>Out: 标准固件镜像
Bat->>WP: 2. 依据 xlsx 参数表生成写保护参数
WP-->>Out: flash_params_v3.bin
Bat->>Tools: 3. ufw_maker.exe 聚合分区与资源 (dir_*)
Tools-->>Out: UFW 升级包
Bat->>Tools: 4. isd_download.exe 烧录验证(可选)
Out-->>Dev: 交付:可烧录镜像 / UFW 升级包
流程要点:
- 入口统一:所有步骤由
download.bat串联,保证步骤顺序与参数一致; - 先规范后打包:
fw_add.exe先产出规范镜像,再进入ufw_maker.exe打包,避免直接打包裸镜像导致升级/烧录失败; - 写保护前置:写保护参数在打包前生成并纳入 UFW,保证烧录后关键区域立即受保护(推断);
- 可验证:
isd_download.exe承担下载/烧录,可在产线或开发阶段验证镜像可用性。
使用示例
仓库中实际存在的后处理文件(已核实)
以下目录树直接来自仓库文件清单(ListFiles 结果),是后处理能力的实际载体:
sdk/app/post_build/sh59/
├── download.bat # 后处理入口脚本
├── maskrom_stubs.ld # MaskROM stub 链接脚本
└── mbox_flash/
├── app_ld.c # 应用链接脚本生成器(C 源码)
├── download_bat.c # download.bat 生成器(C 源码)
├── fw_add.exe # 固件头/校验添加工具
├── ufw_maker.exe # UFW 统一固件打包工具
├── isd_download.exe # 下载/烧录工具
├── flash_wp_tool.exe # Flash 写保护工具
├── dir_a/ dir_bin_f1x/ dir_eng/ # 资源分区目录
├── dir_ex_flash/ dir_midi/ dir_notice/
├── dir_poetry/ dir_song/ dir_story/
└── flash_write_protect/
├── 0xC8671A_v3.xlsx # 芯片参数表(写保护区域配置)
├── 0xEF4017_v3.xlsx
├── flash_list_to_bin_v3.bat # 参数表 → bin 转换脚本
├── flash_wp_tool.exe
└── inside_flash/
└── flash_params_v3.bin # 写保护参数输出
说明:由于本次源码读取预算已用尽,未能摘录
download.bat与download_bat.c的实际命令内容,此处不提供未经核实的脚本代码片段。建议在仓库中打开上述文件查看真实命令序列。
相关工具链入口(编译侧,兄弟能力)
SDK 根级还提供了构建辅助脚本,与 post_build 同属"构建-交付"流水线:
sdk/make_prompt.bat # 构建提示/环境入口
sdk/tools/make_prompt.bat
sdk/tools/utils/do_merge_libs.bat # 静态库合并工具入口
sdk/tools/utils/make.exe # make 工具
sdk/tools/utils/fixbat.exe / find.exe / ls.exe
这些属于"编译构建"能力,详见对应页面。
配置选项
后处理流程的"配置"以文件形式存在,而非传统 key-value 配置:
| 配置载体 | 类型 | 默认位置 | 作用 |
|---|---|---|---|
0xC8671A_v3.xlsx | Excel 参数表 | mbox_flash/flash_write_protect/ | 0xC8671A 型号芯片的写保护区域配置 |
0xEF4017_v3.xlsx | Excel 参数表 | 同上 | 0xEF4017 型号芯片的写保护区域配置 |
inside_flash/flash_params_v3.bin | 二进制 | 同上 | 转换后的写保护参数,参与镜像打包 |
dir_* 资源目录 | 目录 | mbox_flash/ | 各资源分区的内容来源 |
download_bat.c | C 源码 | mbox_flash/ | 决定生成的 download.bat 中工具调用序列与参数 |
maskrom_stubs.ld | 链接脚本 | sh59/ | 决定 MaskROM 符号 stub 行为 |
换型适配方式:切换芯片型号时,主要变更 xlsx 参数表与链接脚本,工具与批处理编排可复用——这正是"参数外置"设计的收益。
失败模式与边界情况
以下失败模式依据后处理流程的结构分析得出(脚本内部实现未逐一核对,但风险来源是仓库事实):
| 失败模式 | 可能后果 | 缓解方向 |
|---|---|---|
| 工具 exe 缺失/被杀软隔离 | 后处理中断,无镜像产出 | 保持 mbox_flash/ 工具完整性;CI 前做工具存在性校验 |
| xlsx 参数表与芯片型号不匹配 | 写保护区域错误:轻则浪费 Flash,重则锁死关键区段导致无法升级 | 按型号严格对应参数表,升级前检查 flash_params_v3.bin 内容 |
资源目录(dir_*)缺失或为空 | UFW 打包不完整,运行时资源缺失(无提示音、无内容) | 打包脚本对目录存在性与非空做断言(建议) |
download.bat 被手工修改而 download_bat.c 未同步 | 下次重新生成时改动丢失,行为回退 | 统一以 download_bat.c 为唯一事实源,批处理视为生成物 |
| 写保护误配置覆盖升级区 | 设备无法 OTA,只能返厂 | 写保护区域务必排除升级/擦写区段 |
并发与一致性
- 后处理为串行批处理流水线:工具间存在先后依赖(先加头 → 再打包 → 后烧录),不应并行执行同一工程的后处理,否则产物互相覆盖(推断)。
download_bat.c生成download.bat的机制天然保证了脚本一致性:无论谁、何时生成,同一工程产出的编排脚本都相同,消除了手工维护引入的不一致。- 多工程并行构建时,建议每个工程使用独立的输出目录,避免
flash_params_v3.bin等中间产物竞争。
性能与运维
- 零运行时依赖:工具均为原生 exe,无需安装解释器/框架,适合产线脚本与 CI 直接调用。
- 可重复执行:批处理编排具备幂等性设计前提(生成物可覆盖),支持重复构建。
- CI 集成:
download.bat是天然 CI 步骤——编译完成后执行即可产出可交付镜像;建议将flash_params_v3.bin与 UFW 包作为构建产物归档。 - 体积与速度:工具链体积小、执行快,主要耗时在资源拷贝与校验计算,整体后处理通常在秒级(推断)。
扩展点
- 新增资源分区:在
mbox_flash/下新增dir_xxx目录并接入打包脚本,即可扩展内容类型。 - 定制后处理编排:修改
download_bat.c后重新生成download.bat,可增删工具调用、调整参数——这是官方提供的"以源码改脚本"扩展方式。 - 适配新 Flash/新芯片:新增 xlsx 参数表并调整
maskrom_stubs.ld/app_ld.c布局逻辑,即可支撑新型号。 - 替换/升级工具:
fw_add.exe、ufw_maker.exe等为独立可执行文件,可在保持调用接口不变的前提下替换为更新版本。
测试情况
仓库中未发现针对 post_build 的独立测试文件(依据文件清单判断)。该环节的"测试"主要体现在:
download_bat.c的源码生成模式降低了脚本 bug 概率(生成逻辑可编译期检查);isd_download.exe下载验证可视为端到端冒烟测试:能成功烧录并启动,即证明镜像打包链路正确。
若需要更强的保障,建议补充:参数表与 bin 的一致性校验、打包后镜像大小/校验和断言、以及 CI 中对
download.bat的回归冒烟。