From 508188606ec5b9a91273cf9270f611e35bdb5571 Mon Sep 17 00:00:00 2001 From: yelvlab Date: Mon, 23 Mar 2026 20:36:02 +0800 Subject: [PATCH] =?UTF-8?q?feature(fill):=E6=B7=BB=E5=8A=A0=E8=A1=A5?= =?UTF-8?q?=E9=BD=90=E6=95=B4=E9=A1=B5=E6=96=B9=E4=BE=BFOTA=E7=9A=84?= =?UTF-8?q?=E8=84=9A=E6=9C=AC=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 24 ++++++++++++++++ fill_bin.py | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 fill_bin.py diff --git a/README.md b/README.md index 24d3c89..c6ec464 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,30 @@ openocd -f interface/cmsis-dap.cfg -f target/gd32e23x.cfg \ JFlash -openprj project.jflash -open merged.bin,0x08000000 -auto -exit ``` +## 升级包整页补齐 + +如果 Bootloader 只支持整页传输(GD32E230F8 每页 1KB),可在打包升级文件前执行补齐脚本。 + +```bash +python fill_bin.py [-o 输出文件] [--page-size 1024] [--fill 0xFF] +``` + +### 示例 + +使用默认参数(1KB 页、0xFF 补齐): + +```bash +python fill_bin.py CeramixNano-MB_V1.0.9_APP_2026-03-22.bin +``` + +指定输出文件名: + +```bash +python fill_bin.py CeramixNano-MB_V1.0.9_APP_2026-03-22.bin -o CeramixNano-MB_V1.0.9_APP_2026-03-22_UPDATE.bin +``` + +脚本会将文件尾部补足到页大小的整数倍;若输入文件本身已对齐,会原样输出。 + ## 安全校验 脚本内置以下校验,不满足时会报错退出: diff --git a/fill_bin.py b/fill_bin.py new file mode 100644 index 0000000..0e97569 --- /dev/null +++ b/fill_bin.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python3 +""" +将固件 bin 文件尾部补齐到整页大小,便于仅支持整页传输的 Bootloader 升级。 + +默认参数针对 GD32E230F8: +- 页大小: 1024 字节 +- 填充值: 0xFF + +用法: + python fill_bin.py firmware.bin + python fill_bin.py firmware.bin -o firmware_UPDATE.bin + python fill_bin.py firmware.bin --page-size 1024 --fill 0xFF +""" + +import argparse +import os +import sys + + +def build_default_output_path(input_path): + base, ext = os.path.splitext(input_path) + return f"{base}_UPDATE{ext}" + + +def pad_to_page(data, page_size, fill_byte): + remainder = len(data) % page_size + if remainder == 0: + return data, 0 + + pad_len = page_size - remainder + padded = data + bytes([fill_byte]) * pad_len + return padded, pad_len + + +def main(): + parser = argparse.ArgumentParser(description="将固件尾部补齐到整页大小") + parser.add_argument("input", help="输入固件 bin 路径") + parser.add_argument("-o", "--output", default=None, help="输出文件路径 (默认: 输入文件名_UPDATE.bin)") + parser.add_argument("--page-size", type=int, default=1024, help="Flash 页大小,单位字节 (默认: 1024)") + parser.add_argument("--fill", default="0xFF", help="补齐字节值,支持十进制或十六进制 (默认: 0xFF)") + args = parser.parse_args() + + if args.page_size <= 0: + print("错误:--page-size 必须大于 0", file=sys.stderr) + sys.exit(1) + + try: + fill_byte = int(args.fill, 0) + except ValueError: + print(f"错误:--fill 无法解析为整数: {args.fill}", file=sys.stderr) + sys.exit(1) + + if fill_byte < 0 or fill_byte > 0xFF: + print("错误:--fill 必须在 0~255 范围内", file=sys.stderr) + sys.exit(1) + + if not os.path.isfile(args.input): + print(f"错误:找不到输入文件 {args.input}", file=sys.stderr) + sys.exit(1) + + output_path = args.output if args.output else build_default_output_path(args.input) + + with open(args.input, "rb") as f: + data = f.read() + + padded_data, pad_len = pad_to_page(data, args.page_size, fill_byte) + + with open(output_path, "wb") as f: + f.write(padded_data) + + print(f"处理完成: {output_path}") + print(f" 原始大小: {len(data)} 字节") + print(f" 页大小 : {args.page_size} 字节") + print(f" 补齐大小: {pad_len} 字节") + print(f" 输出大小: {len(padded_data)} 字节") + + if pad_len == 0: + print(" 说明 : 输入文件已是整页对齐,已原样输出") + + +if __name__ == "__main__": + main()