相关仓库: - 网关产品仓:https://github.com/ffffxxxjjj/gateway - 参考仓 h743-hello:https://github.com/ffffxxxjjj/h743-hello - 签名打包服务 sign:https://github.com/ffffxxxjjj/sign
本文件是固件版本块的唯一规格。型号、固件名、版本、构建日期、 构建时间只从签名的包头/版本块里读,绝不从文件名解析; 文件名只当人的标签(下载、管理页认),设备根本不看文件名。
0x1000(从 bin 起始算,不是从 Flash 基址算)。0x1000 至 0x10E3,含端点为 0x1000 + 228)。app/package.sh)在编出 bin 后,把版本块打进该位置。| 偏移 | 长度 | 内容 |
|---|---|---|
[0..4] |
4 | 魔数,ASCII FWVR |
[4] |
1 | 格式字节,必须为 2 |
[5..105] |
100 | 型号,ASCII、零填充(如 stm32h743vi) |
[105..205] |
100 | 固件名,ASCII、零填充(如 gateway) |
[205..211] |
6 | 版本:major、minor、patch,3 个 u16 小端(依次在 205、207、209) |
[211..219] |
8 | 构建日期,8 位 ASCII YYYYMMDD |
[219..225] |
6 | 构建时间,6 位 ASCII HHMMSS(UTC,不是本地时间) |
[225..228] |
3 | 保留,必须为 0 |
sign-tool 读版本块时(read_version_block):
0x1000 + 228,或魔数不是 FWVR → 视为“没有版本块”
(返回 None,pack 拒绝打包,报“没有版本块”)。2;版本块格式 2 不要与 GWPK 包头格式 3 混淆:版本块是
固件 bin 里的身份块(格式 2);GWPK 包头是 sign-tool 打包后
的共用包头(格式 3,共 312 字节)。两者是两层东西。
网关应用的打包脚本(app/package.sh)流程:
cargo build 编出 ELF;cargo objcopy -O binary 转成 bin,放 dist/,带版本号命名
(如 gateway-app-v0.1.0.bin、gateway-app-v0.1.0-release.bin);app/tools/stamp_version.py 把版本块打进 bin 偏移 0x1000:stm32h743vi,固件名固定 gateway;app/Cargo.toml 的 version(如 0.1.0);date -u),不是本地时间;hello 的打包脚本没有打版本块这步(hello 的 bin 不需要被 sign-tool 打包);网关应用的打包脚本必须补这步,否则 sign-tool pack 读不到身份,无法打包。
应用的链接脚本(app/link.x,基于 cortex-m-rt 的 link.x 改)
在 Flash 布局里给版本块留了固定位置:
0x1000 处(即 bin 偏移 0x1000),
长度 228 字节,由应用源码里的占位静态变量
(#[link_section = ".version_block"],#[used])占据;.text)从版本块之后开始,不与版本块重叠。验证方法(沙盒/CI 可做,不用上板):
# 编应用(debug 或 release)
cargo build --target thumbv7em-none-eabihf
# 转 bin
cargo objcopy --bin gateway-app --target thumbv7em-none-eabihf -- -O binary /tmp/app.bin
# 查版本块位置(打戳前应全零,打戳后应为 FWVR + 格式 2)
python3 -c "
data = open('/tmp/app.bin', 'rb').read()
print('len', len(data))
print('region', data[0x1000:0x1000+16])
"
打戳前该区域必须全零(说明留位成功);若不是全零, 说明链接脚本没有留位,打包脚本会失败退出(安全规则), 不要绕过它强行写。
以下是一组测试向量里的版本块内容(仅作格式示例,
不是网关应用骨架的实际版本;骨架的实际版本取自其
Cargo.toml,构建日期/时间取打包时的 UTC 时间):
stm32h743vigateway1.2.320251031171000(UTC)对应的版本块字节(前 16 字节):46 57 56 52 02(FWVR + 格式 2)
后跟型号、固件名(零填充)、版本(major=1、minor=2、patch=3,
依次为 01 00、02 00、03 00 小端,在 205、207、209)。