补上命令行编译和固件打包:一次出带 Key / 不带 Key 两套,USB 只烧选中的那套。

- Makefile 源文件列表对齐 CodeBlocks,命令行 make 能编过;编完自动打到 ../release/
- 新增 tools/pack_firmware:按版本打出烧录器 / APP UFW / 网关双备份包,带 Key 和不带 Key 各一套
- build.bat key 烧带 Key,默认或不带参数烧 nokey;另一套只生成不写 Flash
- 删掉未使用的 version.txt;release/ 不进仓库
This commit is contained in:
2026-08-21 15:55:38 +08:00
parent c0b5fcc4c5
commit a4cdf65a4f
11 changed files with 384 additions and 226 deletions
+12
View File
@@ -0,0 +1,12 @@
@echo off
chcp 65001 >nul
cd /d "%~dp0"
powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0pack_firmware.ps1"
if errorlevel 1 (
echo.
echo pack failed.
pause
exit /b 1
)
echo.
pause
+169
View File
@@ -0,0 +1,169 @@
# pack_firmware.ps1
# Extract JieLi burn files and zip as Project_Version_Date.
# ASCII only: Windows PowerShell 5.1 mis-parses UTF-8 without BOM.
#
# Usage:
# make - build + download.bat + pack
# make pack - pack only
# pack_firmware.bat
[CmdletBinding()]
param(
[string]$ProjectName = "JL7016_MOD_FW",
[string]$SdkRoot = ""
)
$ErrorActionPreference = "Stop"
$exitCode = 0
try {
$RepoRoot = Split-Path -Parent $PSScriptRoot
if ([string]::IsNullOrWhiteSpace($SdkRoot)) {
$SdkRoot = Join-Path $RepoRoot "JBao_JL7016_MOD_FW"
}
$VersionHeader = Join-Path $SdkRoot "apps\usr_mcu_bridge\business\mcu_version.h"
$DownloadDir = Join-Path $SdkRoot "cpu\br28\tools\download\earphone"
$ReleaseRoot = Join-Path $RepoRoot "release"
function Read-FwVersion {
param([string]$HeaderPath)
if (-not (Test-Path -LiteralPath $HeaderPath)) {
throw "version header not found: $HeaderPath"
}
$text = Get-Content -LiteralPath $HeaderPath -Raw -Encoding UTF8
$major = $null
$minor = $null
$patch = $null
if ($text -match '(?m)^\s*#define\s+MCU_BLE_FW_VER_MAJOR\s+\((\d+)u?\)') {
$major = $Matches[1]
}
if ($text -match '(?m)^\s*#define\s+MCU_BLE_FW_VER_MINOR\s+\((\d+)u?\)') {
$minor = $Matches[1]
}
if ($text -match '(?m)^\s*#define\s+MCU_BLE_FW_VER_PATCH\s+\((\d+)u?\)') {
$patch = $Matches[1]
}
if (($null -eq $major) -or ($null -eq $minor) -or ($null -eq $patch)) {
throw "cannot parse MCU_BLE_FW_VER_* from $HeaderPath"
}
return "V$major.$minor.$patch"
}
$PackItems = @(
@{ Name = "jl_isd_nokey.fw"; Fallback = "jl_isd.fw"; Suffix = "_nokey_burner.fw"; Required = $true; NoteKey = "burner_nokey" },
@{ Name = "update_nokey.ufw"; Fallback = "update.ufw"; Suffix = "_nokey_app_ota.ufw"; Required = $false; NoteKey = "app_nokey" },
@{ Name = "db_update_data_nokey.bin"; Fallback = "db_update_data.bin"; Suffix = "_nokey_gateway_ota.bin"; Required = $false; NoteKey = "gw_nokey" },
@{ Name = "jl_isd_key.fw"; Fallback = ""; Suffix = "_key_burner.fw"; Required = $false; NoteKey = "burner_key" },
@{ Name = "update_key.ufw"; Fallback = ""; Suffix = "_key_app_ota.ufw"; Required = $false; NoteKey = "app_key" },
@{ Name = "db_update_data_key.bin"; Fallback = ""; Suffix = "_key_gateway_ota.bin"; Required = $false; NoteKey = "gw_key" }
)
$NoteZh = @{}
$notesFile = Join-Path $PSScriptRoot "pack_notes_zh.txt"
Get-Content -LiteralPath $notesFile -Encoding UTF8 | ForEach-Object {
if ($_ -match '^([^|]+)\|(.*)$') {
$NoteZh[$Matches[1].Trim()] = $Matches[2].Trim()
}
}
Write-Host "========================================"
Write-Host " pack firmware"
Write-Host "========================================"
$version = Read-FwVersion -HeaderPath $VersionHeader
$dateStr = Get-Date -Format "yyMMdd"
$pkgName = "${ProjectName}_${version}_${dateStr}"
Write-Host "project : $ProjectName"
Write-Host "version : $version (from mcu_version.h)"
Write-Host "date : $dateStr"
Write-Host "source : $DownloadDir"
Write-Host ""
if (-not (Test-Path -LiteralPath $DownloadDir)) {
throw "download dir not found, compile the project first: $DownloadDir"
}
$copied = @()
foreach ($item in $PackItems) {
$src = Join-Path $DownloadDir $item.Name
if (-not (Test-Path -LiteralPath $src) -and $item.Fallback) {
$src = Join-Path $DownloadDir $item.Fallback
}
if (Test-Path -LiteralPath $src) {
$item.Src = $src
$item.Dest = $pkgName + $item.Suffix
$copied += $item
continue
}
if ($item.Required) {
throw "missing required file: $($item.Name); please build the firmware first."
}
Write-Host "[skip] $($item.Name) not generated"
}
if ($copied.Count -eq 0) {
throw "no firmware files found in $DownloadDir"
}
$pkgDir = Join-Path $ReleaseRoot $pkgName
if (Test-Path -LiteralPath $pkgDir) {
Remove-Item -LiteralPath $pkgDir -Recurse -Force
}
New-Item -ItemType Directory -Path $pkgDir -Force | Out-Null
foreach ($item in $copied) {
Copy-Item -LiteralPath $item.Src -Destination (Join-Path $pkgDir $item.Dest) -Force
$size = (Get-Item -LiteralPath $item.Src).Length
Write-Host ("[copy] {0,-28} -> {1} ({2} bytes)" -f (Split-Path $item.Src -Leaf), $item.Dest, $size)
}
$fileList = New-Object System.Collections.Generic.List[string]
foreach ($item in $copied) {
$note = $NoteZh[$item.NoteKey]
[void]$fileList.Add((" {0}" -f $item.Dest))
[void]$fileList.Add((" {0}" -f $note))
}
$tplPath = Join-Path $PSScriptRoot "pack_readme_zh.txt"
$readme = Get-Content -LiteralPath $tplPath -Raw -Encoding UTF8
$readme = $readme.Replace("{{PKG_NAME}}", $pkgName)
$readme = $readme.Replace("{{PROJECT}}", $ProjectName)
$readme = $readme.Replace("{{VERSION}}", $version)
$readme = $readme.Replace("{{DATE}}", (Get-Date -Format "yyyy-MM-dd HH:mm:ss"))
$readme = $readme.Replace("{{FILE_LIST}}", ($fileList -join "`r`n"))
$readme = $readme -replace "`n", "`r`n"
$readme = $readme -replace "`r`r`n", "`r`n"
[System.IO.File]::WriteAllText(
(Join-Path $pkgDir "README.txt"),
$readme,
[System.Text.UTF8Encoding]::new($true)
)
$zipPath = Join-Path $ReleaseRoot "$pkgName.zip"
if (Test-Path -LiteralPath $zipPath) {
Remove-Item -LiteralPath $zipPath -Force
}
Compress-Archive -Path (Join-Path $pkgDir "*") -DestinationPath $zipPath -CompressionLevel Optimal
Write-Host ""
Write-Host "folder : $pkgDir"
Write-Host "zip : $zipPath"
Write-Host "done."
Write-Host "========================================"
} catch {
Write-Host ""
Write-Host "pack failed: $($_.Exception.Message)"
$exitCode = 1
}
exit $exitCode
+6
View File
@@ -0,0 +1,6 @@
burner_nokey|不带 Key:产线批量烧录器镜像(调试、未加密芯片)
app_nokey|不带 Key:手机 APP / 小程序 OTAUFW
gw_nokey|不带 Key55AA 服务器 OTA / 网关 OTA(杰理双备份包)
burner_key|带 Key:产线批量烧录器镜像(烧录器需配置同一把 key)
app_key|带 Key:手机 APP / 小程序 OTAUFW
gw_key|带 Key55AA 服务器 OTA / 网关 OTA(杰理双备份包)
+20
View File
@@ -0,0 +1,20 @@
包名 : {{PKG_NAME}}
项目 : {{PROJECT}}
版本 : {{VERSION}}
日期 : {{DATE}}
文件说明:
{{FILE_LIST}}
使用说明:
1. 批量烧录器:打开 *_burner.fw。
2. 杰理 UFW 通道(部分 APP / 小程序):上传 *_app_ota.ufw。
3. 走本协议 55AA 的服务器 OTA(APP / 小程序 / 网关都一样):上传 *_gateway_ota.bin。
Type=0x02BLE),不要传 ufw / fw / 普通 app.bin。
4. 杰理网关若单独吃双备份包:同样用 *_gateway_ota.bin。
不带 Key(*_nokey_*):调试、未加密芯片。
带 Key(*_key_*):加密镜像,烧录器 / 升级工具必须配置同一把 key(RS-5B88)。
本包不包含 .key 文件,请不要把工厂 key 发给终端用户。
本机 USB.\build.bat 默认烧 nokey.\build.bat key 烧带 Key。两套文件都会打包。
+45
View File
@@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
"""Align Makefile c_SRC_FILES with AC701N.cbp compile units."""
from __future__ import print_function
import re
from pathlib import Path
root = Path(__file__).resolve().parents[1] / "JBao_JL7016_MOD_FW"
cbp = (root / "AC701N.cbp").read_text(encoding="utf-8")
mk_path = root / "Makefile"
mk = mk_path.read_text(encoding="utf-8")
cbp_cs = []
for m in re.finditer(r'<Unit filename="([^"]+\.c)"', cbp):
rel = m.group(1).replace("\\", "/")
if (root / rel).is_file():
cbp_cs.append(rel)
# keep order as in cbp, unique
seen = set()
ordered = []
for rel in cbp_cs:
if rel not in seen:
seen.add(rel)
ordered.append(rel)
block_lines = ["c_SRC_FILES := \\"]
for i, rel in enumerate(ordered):
if i < len(ordered) - 1:
block_lines.append("\t{} \\".format(rel))
else:
block_lines.append("\t{}".format(rel))
block_lines.append("")
new_block = "\n".join(block_lines) + "\n"
pat = re.compile(
r"# 需要编译的 \.c 文件\nc_SRC_FILES := \\(?:\n\t[^\n]+)*\n\n",
re.M,
)
if not pat.search(mk):
raise SystemExit("c_SRC_FILES block not found")
mk2 = pat.sub("# 需要编译的 .c 文件\n" + new_block + "\n", mk, count=1)
mk_path.write_text(mk2, encoding="utf-8", newline="\n")
print("cbp c files:", len(ordered))
print("makefile bytes:", mk_path.stat().st_size)