feat(pack): v2 双固件 profile 打包 — fw_pack 公共库 + CLI 重构 + GUI 打包弹窗
This commit is contained in:
@@ -26,6 +26,8 @@ DAPLink Flash — GD32 固件烧录 · 补齐 · 镜像拼接 — 入口与命
|
||||
python flash_gui.py --reset 复位运行
|
||||
python flash_gui.py --pad app.bin 补齐到 1K 边界(app_pad.bin)
|
||||
python flash_gui.py --merge bl.bin app.bin 拼接整片镜像(*_BL.bin)
|
||||
python flash_gui.py --pack a.bin b.bin --pack-bl bl.bin
|
||||
v2 双固件打包(UPDATE/B/FULL+MD5)
|
||||
python flash_gui.py --version 打印 OpenOCD 版本
|
||||
"""
|
||||
|
||||
@@ -40,6 +42,14 @@ import openocd_runner
|
||||
from fw_image import (APP_ADDR_DEFAULT, FLASH_BASE_DEFAULT, FLAG_ADDR_DEFAULT,
|
||||
FLAG_VALUE_DEFAULT, merge_firmware, pad_bin, parse_int)
|
||||
|
||||
# fw_pack (v2 双固件打包公共库) 位于仓库根目录: 源码模式补 sys.path,
|
||||
# 打包模式(PyInstaller --paths+hiddenimport)由运行库提供
|
||||
_REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
|
||||
if os.path.isfile(os.path.join(_REPO_ROOT, 'fw_pack.py')) \
|
||||
and _REPO_ROOT not in sys.path:
|
||||
sys.path.insert(0, _REPO_ROOT)
|
||||
import fw_pack
|
||||
|
||||
|
||||
def _toolchain(args):
|
||||
"""命令行工具链解析: 参数 > 配置文件 > 自动定位(内置/本机/PATH)"""
|
||||
@@ -121,6 +131,37 @@ def run_merge(args):
|
||||
return 0
|
||||
|
||||
|
||||
def run_pack(args):
|
||||
"""v2 双固件打包(GUI '打包 v2' 的命令行形态, 共用 fw_pack.pack_all)"""
|
||||
try:
|
||||
fw_pack.self_test()
|
||||
profile = fw_pack.load_profile(args.pack_profile)
|
||||
except fw_pack.FwPackError as exc:
|
||||
sys.exit(f'{exc}')
|
||||
found = {}
|
||||
for path in args.pack:
|
||||
if not os.path.isfile(path):
|
||||
sys.exit(f'找不到文件: {path}')
|
||||
try:
|
||||
slot = fw_pack.detect_slot(open(path, 'rb').read(), profile)
|
||||
except fw_pack.FwPackError as exc:
|
||||
sys.exit(f'{path}: {exc}')
|
||||
if slot in found:
|
||||
sys.exit(f'{path} 与 {found[slot]} 都被识别为 {slot.upper()} 包, '
|
||||
f'一个槽只能有一个输入')
|
||||
found[slot] = path
|
||||
a, b = found.get('a'), found.get('b')
|
||||
if not a and not b:
|
||||
sys.exit('未提供可识别的固件输入 (A 包或 B 包)')
|
||||
try:
|
||||
fw_pack.pack_all(args.pack_profile, a, b_path=b,
|
||||
bl_path=args.pack_bl or None, out_dir=args.output,
|
||||
make_full=not args.pack_no_full)
|
||||
except fw_pack.FwPackError as exc:
|
||||
sys.exit(f'打包失败: {exc}')
|
||||
return 0
|
||||
|
||||
|
||||
def _ensure_parent(path):
|
||||
parent = os.path.dirname(os.path.abspath(path))
|
||||
if parent:
|
||||
@@ -145,9 +186,18 @@ def main():
|
||||
op.add_argument('--pad', metavar='FILE', dest='pad', help='补齐 BIN 到页边界')
|
||||
op.add_argument('--merge', nargs=2, metavar=('BL', 'APP'),
|
||||
help='拼接 Bootloader + APP → 整片镜像')
|
||||
op.add_argument('--pack', nargs='+', metavar='BIN',
|
||||
help='v2 双固件打包: A/B 包自动识别 → UPDATE/B/FULL+MD5')
|
||||
ap.add_argument('--pack-profile', default='ceramixnano_mb_v51',
|
||||
help='--pack 布局 profile(内置名或 JSON 路径)')
|
||||
ap.add_argument('--pack-bl', default=None, metavar='BIN',
|
||||
help='--pack 使用的 Bootloader bin')
|
||||
ap.add_argument('--pack-no-full', action='store_true',
|
||||
help='--pack 只出 UPDATE/B 包, 不拼 FULL')
|
||||
ap.add_argument('--align', default='1024', help='--pad 对齐字节(默认 1024)')
|
||||
ap.add_argument('--pad-byte', default='0xFF', help='--pad 填充字节(默认 0xFF)')
|
||||
ap.add_argument('-o', '--output', help='--pad/--merge 输出路径(默认自动命名)')
|
||||
ap.add_argument('-o', '--output',
|
||||
help='输出路径: --pad/--merge 为文件, --pack 为目录(默认自动命名)')
|
||||
ap.add_argument('--app-addr', default='0x%08X' % APP_ADDR_DEFAULT,
|
||||
help='--merge APP 地址(默认 0x08002000)')
|
||||
ap.add_argument('--flag-addr', default='0x%08X' % FLAG_ADDR_DEFAULT,
|
||||
@@ -174,6 +224,8 @@ def main():
|
||||
ap.add_argument('--scripts', help='OpenOCD scripts 目录(默认自动定位)')
|
||||
args = ap.parse_args()
|
||||
|
||||
if args.pack:
|
||||
sys.exit(run_pack(args))
|
||||
if args.pad:
|
||||
sys.exit(run_pad(args))
|
||||
if args.merge:
|
||||
|
||||
Reference in New Issue
Block a user