芯片配置工具与下载支持
本页介绍 fw-AC63_BT_SDK 中 AC63 系列芯片(以 bd19/AC632N 为代表)的配置工具与下载(烧录)支持两大能力:前者是基于杰理 JL 工具链的图形化配置工程(.jlxproj + Lua 脚本体系),后者是从编译产物生成可烧录镜像并调用 isd_download.exe 完成下载的整套脚本机制。
Purpose and Scope
本页覆盖以下内容:
- AC632N 配置工具:
cpu/bd19/tools/AC632N_config_tool/下的入口工程、conf/entry/中的 Lua 配置脚本、conf/output/中的生成产物(cfg_tool.c/h、default_cfg.fw)及其在固件编译中的接入方式。 - 下载/烧录支持:
cpu/bd19/tools/download.c(Shell/Batch 双用途脚本)、download.bat的应用形态分支、isd_config_rule.c生成的isd_config.ini,以及isd_download.exe、fw_add.exe、ufw_maker.exe等工具的协作关系。
以下内容属于兄弟页面,不在本页展开:
- 具体产品案例(手表、音箱、耳机、数传等)各自的
download/<case>/download.bat细节,本页只说明其被调用的分支逻辑; - SDK 整体架构、编译流程(
make/工具链安装),详见 SDK 首页 README 的「编译指南」章节; - 配置工具各模块(蓝牙、充电、提示音等)的业务语义,本页只说明工具机制本身。
Overview
AC63 系列是杰理科技的蓝牙音频 SoC,其 SDK 采用「配置工具 + 脚本下载」两条并行的工程化链路来支撑量产开发:
配置工具链路解决的是"如何把产品参数变成固件代码"。SDK 在 cpu/bd19/tools/AC632N_config_tool/ 中提供了基于 JL 工具链的配置工程(.jlxproj),工程通过一组 Lua 脚本(conf/entry/)描述配置面板的形态、模块使能开关与默认值。开发者双击入口工程即可打开图形界面,勾选/填写产品参数后,工具会生成 cfg_tool.c/h(供固件源码引用的宏与数据结构)以及 default_cfg.fw(默认配置数据文件)。这套设计把"改参数"从手工编辑头文件提升为可视化操作,同时保留了 Lua 脚本的完全可编程性。
下载支持链路解决的是"如何把 elf 变成可烧录镜像并写进芯片"。cpu/bd19/tools/download.c 是一份非常巧妙的双用途文件:在编译时若定义了 __SHELL__,它表现为 POSIX shell 脚本(Linux 服务器端);否则表现为 Windows 批处理。它负责把 sdk.elf 按段拆出(.text/.data/.data_code/.overlay_*/.common/.overlay_bank0-20),用 lz4_packet 对常驻段与 bank 段做字典压缩,再按固定顺序拼接成 app.bin,最后依据编译宏(手表/音箱/耳机/数传)调用对应的 download/<case>/download.bat,由 isd_download.exe 完成 USB/串口烧录。同时 isd_config_rule.c 以 C 注释形式保存 isd_config.ini 的生成规则(含 [FW_ADDITIONAL] 附加文件表),供 strip-ini 与下载工具解析。
Architecture
flowchart TD
subgraph sg_ConfigTool["AC632N 配置工具 (conf/entry Lua 脚本体系)"]
Entry["AC632N_配置工具入口.jlxproj"]
UserCfg["user_cfg.lua"]
FwCommon["fw_common.lua"]
FwCreate["fw_create.lua"]
FwEdit["fw_edit.lua"]
LangEn["lang_en.lua"]
Entry --> UserCfg
Entry --> FwCommon
Entry --> FwCreate
Entry --> FwEdit
Entry --> LangEn
UserCfg --> Output["conf/output 生成"]
end
subgraph sg_Output["配置输出产物"]
Output --> CfgC["cfg_tool.c / cfg_tool.h"]
Output --> DefaultCfg["default_cfg.fw"]
Output --> StateLua["cfg_tool_state_complete.lua"]
end
subgraph sg_Download["下载支持链路"]
Elf["sdk.elf (编译产物)"] --> DownloadC["download.c<br/>(Shell / Batch 双用途)"]
DownloadC --> AppBin["app.bin"]
DownloadC --> DownloadBat["download.bat (按 case 分发)"]
IsdRule["isd_config_rule.c"] --> IsdIni["isd_config.ini"]
DownloadBat --> IsdDownload["isd_download.exe"]
IsdIni --> IsdDownload
IsdDownload --> Chip["AC63 芯片 Flash"]
end
CfgC --> Elf
DefaultCfg --> AppBin
架构说明:
- 配置工具侧:入口工程
.jlxproj是 JL 工具链的工程描述,加载conf/entry/下各 Lua 脚本;其中user_cfg.lua是"元配置"(配置工具自身的配置),决定产品名、版本号、开发/发布状态与各模块面板是否显示;其余脚本(fw_create.lua/fw_edit.lua/ufw_edit.lua等)实现固件/升级包的创建与编辑逻辑。工具运行后把结果写入conf/output/:cfg_tool.c/h是固件编译直接包含的配置头,default_cfg.fw是出厂默认配置,cfg_tool_state_complete.lua记录工具完成状态。 - 下载侧:
download.c是整条链路的枢纽,它同时是"脚本"(被download.bat调用)又承载"文件清单"(注释中的files=行),把 elf 加工成app.bin并按应用形态分发到对应子目录脚本,最终由isd_download.exe依据isd_config.ini(来自isd_config_rule.c规则)烧录到芯片。
配置工具:入口工程与 Lua 脚本体系
入口工程 .jlxproj
配置工具的入口是 AC632N_配置工具入口(Config Tools Entry).jlxproj.jlxproj>),这是一个 JL 工具链(JL Toolchain)工程文件。工具链通过该工程加载同目录 conf/entry/ 下的 Lua 脚本,在图形界面中渲染配置面板。之所以用脚本驱动界面,是为了让不同 SDK 版本/不同产品线共享同一套工具外壳,只替换脚本即可改变面板内容——这是杰理工具链的通用扩展机制。
conf/entry/ 脚本职责
| 文件 | 职责 |
|---|---|
user_cfg.lua | 配置工具自身的元配置:FW 版本信息、产品名、开发/发布状态、EQ 工具与编译前工具按钮、模块显示使能 |
fw_common.lua | 固件公共配置项(编译期常量、公共参数) |
fw_create.lua | 固件创建逻辑(编译前工具 fw_create_button_show 控制的入口) |
fw_edit.lua | 固件编辑逻辑(修改已有固件参数) |
ufw_edit.lua | UFW(升级固件)编辑逻辑 |
lang_en.lua | 英文语言包,用于界面国际化 |
app_log.md | 应用说明文档(工具界面上的"应用详细信息") |
version.log | 工具版本历史记录 |
user_cfg.lua 元配置详解
user_cfg.lua 是理解工具行为的钥匙,其关键设计如下:
- 版本与产品标识:
cfg:addKeyInfo("script_version", "AC632N-v0.01-cfg_tool-v0.05")向工具注册脚本版本;product_name = "AC632N"显示在入口界面。 - 状态开关:
config_status = "develop"(开发态)/"release"(发布态)二选一。开发态用于 SDK 内部调试,发布态用于对外发布——同一份脚本通过一行注释切换,避免维护两套配置。 - 按钮控制:
eq_tool_button_show控制 EQ 工具是否打开;fw_create_button_show控制"编译前工具"(固件创建)是否打开,两者独立,可按需裁剪入口界面的复杂度。 - 模块显示使能:
enable_moudles表(注意是moudles而非modules,属 SDK 原始命名,需保持原样)按模块名开关配置面板。例如["charge"] = true、["tone"] = true、["bluetooth"] = true显示充电、提示音、蓝牙面板,而["isdtool"] = false、["audio"] = false隐藏 ISD 工具与音频面板。key_msg是带参数的条目({enable = false, num = 10}),说明模块使能不仅支持布尔值,还支持携带子参数的 table——这是脚本化配置的表达力所在。
配置输出与固件接入
工具运行后把结果写入 conf/output/:
- cfg_tool.h 是生成的 C 头文件骨架,定义了
ENABLE_THIS_MODULE/DISABLE_THIS_MODULE、ENABLE/DISABLE、NO_CONFIG_PORT等宏约定。固件源码中包含该头文件即可按宏条件编译各功能模块,实现"配置驱动代码"。配套的cfg_tool.c则承载实际的数据结构与默认值。 default_cfg.fw(及default/default_cfg.lua)是出厂默认配置数据,extra_tones/*.wtg是额外提示音资源,最终会被打包进固件镜像。
配置工具流程
flowchart LR
Start["双击 .jlxproj 打开入口"] --> Load["加载 conf/entry/*.lua"]
Load --> ReadCfg["读取 user_cfg.lua<br/>(版本/产品名/模块使能)"]
ReadCfg --> CheckStatus{"config_status?"}
CheckStatus -->|"develop"| Dev["开发状态: 暴露调试选项"]
CheckStatus -->|"release"| Rel["发布状态: 仅发布选项"]
Dev --> Modules["按 enable_moudles 渲染模块面板"]
Rel --> Modules
Modules --> Edit["fw_edit / ufw_edit 编辑参数"]
Edit --> Gen["生成 cfg_tool.c/h + default_cfg.fw"]
Gen --> Compile["固件编译引用配置"]
该流程体现了"脚本声明 UI → 面板编辑 → 生成 C/数据产物 → 固件编译消费"的闭环:工具不是一次性配置器,而是与编译流程耦合的代码生成器。fw_create_button_show = true 意味着编译前会自动调用固件创建逻辑(fw_create.lua),确保每次编译都基于最新配置。
下载支持:download.c 双用途脚本
download.c 是整个下载链路的枢纽。它最特别的设计是一份文件、两种运行时:文件开头 #include "app_config.h" 后紧跟 #ifdef __SHELL__ 分支,因此它既是一段"伪 C 代码"(依赖 app_config.h 的宏),又是一个真正的脚本——在 Linux 工具链(__SHELL__ 定义时)表现为 POSIX shell,在 Windows 下表现为批处理。app_config.h 中的宏(如 CONFIG_WATCH_CASE_ENABLE)直接决定脚本的控制流,实现"同一份源码、双平台执行、宏驱动分支"。
Shell 模式(Linux 服务器端)
##!/bin/sh
${OBJDUMP} -D -address-mask=0x1ffffff -print-dbg $1.elf > $1.lst
${OBJCOPY} -O binary -j .text $1.elf text.bin
${OBJCOPY} -O binary -j .data $1.elf data.bin
${OBJCOPY} -O binary -j .data_code $1.elf data_code.bin
${OBJCOPY} -O binary -j .overlay_aec $1.elf aec.bin
${OBJCOPY} -O binary -j .overlay_aac $1.elf aac.bin
${OBJCOPY} -O binary -j .overlay_aptx $1.elf aptx.bin
${OBJCOPY} -O binary -j .common $1.elf common.bin
bank_files=
for i in $(seq 0 20)
do
${OBJCOPY} -O binary -j .overlay_bank$i $1.elf bank$i.bin
if [ ! -s bank$i.bin ]
then
break
fi
bank_files=$bank_files"bank$i.bin 0x0 "
done
echo $bank_files
lz4_packet -dict text.bin -input common.bin 0 $bank_files -o bank.bin
${OBJDUMP} -section-headers -address-mask=0x1ffffff $1.elf
${OBJSIZEDUMP} -lite -skip-zero -enable-dbg-info $1.elf | sort -k 1 > symbol_tbl.txt
cat text.bin data.bin data_code.bin aec.bin aac.bin bank.bin aptx.bin > app.bin
/opt/utils/strip-ini -i isd_config.ini -o isd_config.ini
/* files="app.bin ${CPU}loader.* uboot* ota*.bin p11_code.bin isd_config.ini isd_download.exe fw_add.exe ufw_maker.exe" */
files="app.bin ${CPU}loader.* uboot* ota*.bin p11_code.bin isd_config.ini flash_params.bin"
NICKNAME="${CPU}_sdk"
host-client -project ${NICKNAME}$2 -f ${files} $1.elf
Source: download.c
这段脚本完成四件事:
- 分段提取:用
OBJCOPY把 elf 的各个段转成独立的 bin 文件——.text(代码)、.data(数据)、.data_code(数据段中的可执行代码)、.overlay_aec/.overlay_aac/.overlay_aptx(算法 overlay)、.common(公共常驻段)、.overlay_bank0..20(按 bank 划分的 overlay 段)。bank 循环在遇到空文件时break,保证只处理实际存在的 bank。 - LZ4 字典压缩:
lz4_packet -dict text.bin -input common.bin 0 $bank_files -o bank.bin以text.bin为字典,把common.bin和各 bank 段压缩成bank.bin。这显著节省 Flash 空间——bank 段与常驻代码高度相似,字典压缩可把冗余降到最低。 - 镜像拼接:
cat text.bin data.bin data_code.bin aec.bin aac.bin bank.bin aptx.bin > app.bin按固定地址顺序拼接出最终app.bin。拼接顺序即链接器布局顺序,bootloader 按此顺序加载各段。 - 配置精简与上传:
strip-ini删除isd_config.ini中的注释(减小体积、避免解析歧义);host-client把files=清单(app.bin、${CPU}loader.*、uboot*、ota*.bin、p11_code.bin、isd_config.ini、flash_params.bin等)上传到编译服务器,NICKNAME用于区分项目会话。注释行还列出了上传端所需的下载工具本体:isd_download.exe、fw_add.exe、ufw_maker.exe。
Batch 模式(Windows 本地)
Windows 分支(#else,download.c L46-L89)逻辑与 shell 完全对齐:设置 OBJDUMP=C:\JL\pi32\bin\llvm-objdump.exe、OBJCOPY=C:\JL\pi32\bin\llvm-objcopy.exe,检测 sdk.elf 存在后执行相同的分段、lz4_packet 压缩与 copy /b 拼接,最后 del 清理中间文件。if exist sdk.elf (...) 的保护使未编译时脚本静默跳过镜像生成,避免误报。
应用形态分支与烧录
拼接完成后,脚本按 app_config.h 中的宏分发到对应下载子脚本(download.c L91-L101):
#ifdef CONFIG_WATCH_CASE_ENABLE
call download/watch/download.bat
#elif defined(CONFIG_SOUNDBOX_CASE_ENABLE)
call download/soundbox/download.bat
#elif defined(CONFIG_EARPHONE_CASE_ENABLE)
call download/earphone/download.bat
#elif defined(CONFIG_HID_CASE_ENABLE) ||defined(CONFIG_SPP_AND_LE_CASE_ENABLE)||defined(CONFIG_MESH_CASE_ENABLE)||defined(CONFIG_DONGLE_CASE_ENABLE) //数传
call download/data_trans/download.bat
#else
//to do other case
#endif //endif app_case
Source: download.c
各 download/<case>/download.bat 是产品线专属的下载参数(烧录地址、擦除范围、工具参数),最终都会调用 isd_download.exe 把 app.bin 写入芯片。download.bat 顶层脚本(download.bat)在条件分支末尾 call download/data_trans/download.bat 兜底。
isd_config.ini 规则:isd_config_rule.c
isd_config_rule.c 以 C 注释形式保存 isd_config.ini 的生成规则(该文件由 SDK 构建系统处理成真实 INI)。其中可见 [FW_ADDITIONAL] 附加文件表机制:
[FW_ADDITIONAL]
FILE_LIST = (file = file_authrunFindmyAC632N.tkn: type = 0xec)
Source: isd_config_rule.c
[FW_ADDITIONAL] 允许在固件镜像中附加额外文件(此处为 Find My 认证 token,type = 0xec 标识文件类型),使烧录器能把授权文件与固件一并写入 Flash——这对量产授权类功能至关重要。isd_config.ini 被 strip-ini 精简后,与 app.bin、flash_params.bin 一起交给 isd_download.exe 解析执行。
flowchart TD
Start2["sdk.elf 编译产物"] --> Dump["OBJDUMP 生成 lst<br/>OBJCOPY 分段提取"]
Dump --> Sections["text/data/data_code/aec/aac/aptx/common/bank0-20"]
Sections --> Lz4["lz4_packet 字典压缩<br/>(dict = text.bin)"]
Lz4 --> Cat["按固定顺序拼接 app.bin"]
Cat --> Branch{"应用形态宏?"}
Branch -->|"CONFIG_WATCH_CASE_ENABLE"| Watch["download/watch/download.bat"]
Branch -->|"CONFIG_SOUNDBOX_CASE_ENABLE"| Soundbox["download/soundbox/download.bat"]
Branch -->|"CONFIG_EARPHONE_CASE_ENABLE"| Earphone["download/earphone/download.bat"]
Branch -->|"HID/SPP_LE/MESH/DONGLE"| Datatrans["download/data_trans/download.bat"]
Watch --> Flash["isd_download.exe 烧录"]
Soundbox --> Flash
Earphone --> Flash
Datatrans --> Flash
IsdRule["isd_config_rule.c"] --> Ini["isd_config.ini (strip-ini 精简)"]
Ini --> Flash
Flash --> Chip["AC63 Flash"]
该流程的工程价值在于:一切可脚本化。分段、压缩、拼接、分支、配置精简全部由同一份源码(download.c + isd_config_rule.c)驱动,任何一步都可被宏或命令行参数控制,兼顾了 Linux 服务器批量构建与 Windows 本地单板调试两种场景。
使用示例
示例 1:配置工具元配置(新增/修改模块面板)
以 user_cfg.lua 为例,开发者通过 enable_moudles 控制配置工具界面显示哪些模块面板:
-------------------- 设置编译前工具是否打开 ----------
fw_create_button_show = true;
--fw_create_button_show = false;
-------------------- 设置模块显示使能 --------------
-- true: 模块配置显示使能;
-- false: 模块配置不显示;
-- 注意: adkey 和 iokey 不能同时为true;
enable_moudles = {
["isdtool"] = false,
["audio"] = false,
["charge"] = true,
["status"] = false,
["tone"] = true,
["bluetooth"] = true,
["ble_config"] = false,
["key_msg"] = {enable = false, num = 10},
};
Source: user_cfg.lua
说明:key_msg 条目展示了模块使能不仅支持布尔值,还支持携带 {enable = false, num = 10} 子参数的 table 形式;adkey 与 iokey 互斥的注释提醒开发者按键模块存在硬件复用约束。
示例 2:Windows 下载脚本核心流程(分段 → 压缩 → 拼接)
以下摘自 download.c 的 Windows 批处理分支,展示了镜像构建的完整顺序:
set OBJDUMP=C:\JL\pi32\bin\llvm-objdump.exe
set OBJCOPY=C:\JL\pi32\bin\llvm-objcopy.exe
set INELF=sdk.elf
set LZ4_PACKET=lz4_packet.exe
if exist sdk.elf (
%OBJDUMP% -D -address-mask=0x1ffffff -print-dbg %INELF% > sdk.lst
%OBJCOPY% -O binary -j .text %INELF% text.bin
%OBJCOPY% -O binary -j .data %INELF% data.bin
%OBJCOPY% -O binary -j .data_code %INELF% data_code.bin
%OBJCOPY% -O binary -j .overlay_aec %INELF% aec.bin
%OBJCOPY% -O binary -j .overlay_aac %INELF% aac.bin
%OBJCOPY% -O binary -j .overlay_aptx %INELF% aptx.bin
%OBJCOPY% -O binary -j .common %INELF% common.bin
bankfiles=
for /L %%i in (0,1,20) do (
%OBJCOPY% -O binary -j .overlay_bank%%i %INELF% bank%%i.bin
set bankfiles=!bankfiles! bank%%i.bin 0x0
)
echo %bank_files
%LZ4_PACKET% -dict text.bin -input common.bin 0 %bankfiles% -o bank.bin
%OBJDUMP% -section-headers -address-mask=0x1ffffff %INELF%
%OBJSIZEDUMP% -lite -skip-zero -enable-dbg-info %INELF% > symbol_tbl.txt
copy /b text.bin+data.bin+data_code.bin+aec.bin+aac.bin+bank.bin+aptx.bin app.bin
del bank*.bin common.bin text.bin data.bin bank.bin aac.bin aec.bin aptx.bin
)
Source: download.c
说明:-address-mask=0x1ffffff 限制地址掩码(AC63 可寻址范围),lz4_packet -dict text.bin 以代码段为字典压缩常驻段与 bank 段,copy /b ...+... 的拼接顺序必须与链接器布局一致;脚本末尾清理全部中间文件,保证工作区干净。
示例 3:配置规则中的附加文件表(Find My 认证)
isd_config_rule.c 中 [FW_ADDITIONAL] 段把认证 token 附加进固件镜像:
[FW_ADDITIONAL]
FILE_LIST = (file = file_authrunFindmyAC632N.tkn: type = 0xec)
Source: isd_config_rule.c
说明:该规则在启用 CONFIG_FINDMY_INFO_ENABLE 时生效(第 391 行条件),type = 0xec 是杰理下载工具约定的文件类型标识,烧录时该文件会被写入芯片指定区域,供 Find My 功能在运行时读取。
配置选项
配置工具(user_cfg.lua)
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
script_version(cfg:addKeyInfo) | string | "AC632N-v0.01-cfg_tool-v0.05" | 配置脚本版本,显示在工具信息中 |
product_name | string | "AC632N" | 显示于配置工具入口界面的产品名 |
config_status | string | "develop" | develop(开发态)/ release(发布态) |
eq_tool_button_show | boolean | false | 是否显示 EQ 工具按钮 |
fw_create_button_show | boolean | true | 是否显示编译前固件创建工具按钮 |
enable_moudles["isdtool"] | boolean | false | 是否显示 ISD 工具面板 |
enable_moudles["audio"] | boolean | false | 是否显示音频面板 |
enable_moudles["charge"] | boolean | true | 是否显示充电面板 |
enable_moudles["status"] | boolean | false | 是否显示状态面板 |
enable_moudles["tone"] | boolean | true | 是否显示提示音面板 |
enable_moudles["bluetooth"] | boolean | true | 是否显示蓝牙面板 |
enable_moudles["ble_config"] | boolean | false | 是否显示 BLE 配置面板 |
enable_moudles["key_msg"] | table | {enable = false, num = 10} | 按键消息面板(可带子参数);与 iokey/adkey 存在互斥约束 |
下载支持(app_config.h 宏)
| 宏 | 作用域 | 说明 |
|---|---|---|
__SHELL__ | 编译期 | 定义时 download.c 表现为 POSIX shell(Linux 服务器端),否则为 Windows 批处理 |
CONFIG_WATCH_CASE_ENABLE | 下载分发 | 手表形态,调用 download/watch/download.bat |
CONFIG_SOUNDBOX_CASE_ENABLE | 下载分发 | 音箱形态,调用 download/soundbox/download.bat |
CONFIG_EARPHONE_CASE_ENABLE | 下载分发 | 耳机形态,调用 download/earphone/download.bat |
CONFIG_HID_CASE_ENABLE 等(数传) | 下载分发 | HID/SPP_AND_LE/MESH/DONGLE 数传形态,调用 download/data_trans/download.bat |
CONFIG_FINDMY_INFO_ENABLE | INI 生成 | 启用 [FW_ADDITIONAL] Find My token 附加 |
下载镜像产物清单
| 产物 | 生成方式 | 用途 |
|---|---|---|
app.bin | cat/copy /b 拼接 7 段 | 主烧录镜像 |
bank.bin | lz4_packet 字典压缩 | bank 段压缩包,随 app.bin 拼接 |
sdk.lst / symbol_tbl.txt | OBJDUMP/OBJSIZEDUMP | 反汇编与符号表,供调试 |
isd_config.ini | isd_config_rule.c 规则 + strip-ini 精简 | 下载工具的烧录参数配置 |
flash_params.bin | SDK 构建 | Flash 参数区数据,随 files= 上传 |
失败模式、边界情况与并发注意
按键模块互斥约束
user_cfg.lua 明确注释 adkey 和 iokey 不能同时为true:ADC 按键与 IO 按键在芯片上可能复用同一物理引脚/ADC 通道,同时使能会导致配置工具生成冲突的引脚分配,属于配置期的硬约束。SDK 选择在脚本注释中声明约束,而非在工具中强制校验——这是历史实现的选择,新增模块面板时需自行遵循同类约束。
未编译时镜像生成被跳过
Batch 分支的 if exist sdk.elf (...)(download.c L61)在 sdk.elf 不存在时静默跳过整个分段/压缩/拼接流程。好处是未编译时不会误报错误;代价是后续 call download/<case>/download.bat 若直接用缺失的 app.bin 烧录会失败。因此典型操作顺序是先编译后下载。
bank 段处理差异:Shell 提前退出 vs Batch 固定循环
- Shell 分支用
for i in $(seq 0 20)+if [ ! -s bank$i.bin ]; then break; fi,遇到首个空文件即停止,只收集实际存在的 bank。 - Batch 分支用
for /L %%i in (0,1,20)固定遍历 0..20,每次都会生成/收集bank%%i.bin。
若链接器实际生成的 bank 数量少于 21,两者结果一致;但若 bank 布局不连续(中间存在空洞),Shell 会提前截断而 Batch 仍收集后续 bank——同一 SDK 在两种平台下可能产出不同 bank.bin。这是双用途脚本设计带来的平台差异,移植新 SDK 版本时需保持链接脚本的 bank 连续布局。
拼接顺序与链接布局耦合
text.bin+data.bin+data_code.bin+aec.bin+aac.bin+bank.bin+aptx.bin 的固定顺序对应链接器段布局与 bootloader 的加载顺序。若链接脚本调整段顺序而未同步修改 download.c,会导致芯片启动后段地址错乱。同理,-address-mask=0x1ffffff 与芯片地址空间强相关,换芯片型号时必须核对。
并发与幂等
download.c 生成的中间文件(text.bin、bank*.bin、app.bin)均为固定文件名,且脚本末尾 del 清理(Batch)——多个编译任务并发运行在同一目录会互相覆盖中间文件,产生竞态。SDK 的典型用法是每个工程独立目录或串行构建;Linux 服务器端通过 host-client -project ${NICKNAME}$2 的项目会话隔离上传任务,但本地文件仍共享工作目录。批量流水线场景下应为每个构建分配独立 WORKSPACE。
性能与运维考量
- LZ4 字典压缩:以
text.bin为字典压缩common.bin与 bank 段,是 AC63 镜像瘦身的关键手段。overlay 机制本身就是为了在有限 Flash 上按需加载代码,字典压缩进一步压缩 bank 间冗余,直接决定产品可用的 Flash 余量。 strip-ini精简:删除isd_config.ini注释可减小烧录参数体积并消除解析歧义;该步骤在 Shell 分支通过/opt/utils/strip-ini完成,Batch 分支在工具链侧处理。- 符号表与反汇编:
sdk.lst、symbol_tbl.txt在每次构建时生成,用于崩溃定位(-print-dbg保留调试信息);量产构建可通过调整OBJSIZEDUMP参数减小开销。 - 工具本体:
isd_download.exe(烧录)、fw_add.exe(固件合并/追加)、ufw_maker.exe(升级包制作)为预编译工具,随files=清单分发,运维上需保证与 SDK 版本配套。
扩展点
- 新增配置模块面板:在
enable_moudles表中增加条目(如["my_module"] = true),并在conf/entry/下新增对应 Lua 脚本描述面板字段;工具会依据脚本渲染面板并生成cfg_tool.c/h中的配置宏。 - 新增应用形态下载分支:在 download.c L91-L101 的宏链中增加
#elif defined(CONFIG_XXX_CASE_ENABLE),并新建download/xxx/download.bat定义烧录参数。 - 附加镜像文件:在
isd_config_rule.c的[FW_ADDITIONAL]段追加FILE_LIST条目(参考 Find My token 的type = 0xec写法),即可让烧录器把授权/资源文件与固件一并写入。 - 语言本地化:界面文案维护在
lang_en.lua,新增语言包即可扩展工具的多语言支持。
测试与验证
SDK 未在本目录提供自动化测试用例,验证手段主要是工具自带的版本与状态机制:
conf/entry/version.log记录配置工具的版本历史,用于追溯行为变更;conf/output/cfg_tool_state_complete.lua是工具完成状态文件,构建系统可据此判断配置是否已生成、是否需要在编译前重新生成产物;- 下载链路的验证闭环为:编译 → 运行
download.c生成app.bin→isd_download.exe烧录 → 上电检查 bootloader 日志与功能行为。