增加自动化编译打包脚本
This commit is contained in:
@@ -1,8 +1,15 @@
|
||||
|
||||
# make 编译并下载
|
||||
# make 编译并下载,成功后自动打包到 release/
|
||||
# make pack 仅打包(需已编译生成 jl_isd.fw)
|
||||
# make VERBOSE=1 显示编译详细过程
|
||||
# make clean 清除编译临时文件
|
||||
#
|
||||
# USB 烧录(两套镜像都会生成,只烧其中一套):
|
||||
# .\build.bat 或 .\build.bat nokey -> 烧不带 Key
|
||||
# .\build.bat key -> 烧带 Key
|
||||
# make BURN_KEY=1 与 build.bat key 相同
|
||||
#
|
||||
#
|
||||
# 注意: Linux 下编译方式:
|
||||
# 1. 从 http://pkgman.jieliapp.com/doc/all 处找到下载链接
|
||||
# 2. 下载后,解压到 /opt/jieli 目录下,保证
|
||||
@@ -31,6 +38,11 @@ export PATH:=$(TOOL_DIR);$(PATH)
|
||||
FIXBAT := tools\utils\fixbat.exe # 用于处理 utf8->gbk 编码问题
|
||||
POST_SCRIPT := cpu/br28/tools/download.bat
|
||||
RUN_POST_SCRIPT := cpu\br28\tools\download.bat
|
||||
PACK_SCRIPT := powershell -NoProfile -ExecutionPolicy Bypass -File tools\pack_firmware.ps1
|
||||
# USB: 1/key/yes = flash keyed image; default = nokey
|
||||
ifneq ($(filter 1 key yes,$(BURN_KEY)),)
|
||||
export JL_BURN_KEY := 1
|
||||
endif
|
||||
else
|
||||
# Linux 下工具链位置
|
||||
TOOL_DIR := /opt/jieli/pi32v2/bin
|
||||
@@ -53,6 +65,7 @@ export PATH:=$(TOOL_DIR):$(PATH)
|
||||
FIXBAT := touch # Linux下不需要处理 bat 编码问题
|
||||
POST_SCRIPT := cpu/br28/tools/download.sh
|
||||
RUN_POST_SCRIPT := bash $(POST_SCRIPT)
|
||||
PACK_SCRIPT :=
|
||||
endif
|
||||
|
||||
CC := $(TOOL_DIR)/$(CC)
|
||||
@@ -612,7 +625,7 @@ LINK_AT ?= 1
|
||||
# 表示下面的不是一个文件的名字,无论是否存在 all, clean, pre_build 这样的文件
|
||||
# 还是要执行命令
|
||||
# see: https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html
|
||||
.PHONY: all clean pre_build
|
||||
.PHONY: all clean pre_build pack
|
||||
|
||||
# 不要使用 make 预设置的规则
|
||||
# see: https://www.gnu.org/software/make/manual/html_node/Suffix-Rules.html
|
||||
@@ -621,7 +634,18 @@ LINK_AT ?= 1
|
||||
all: pre_build $(USR_LE_LIB) $(OUT_ELF)
|
||||
$(info +POST-BUILD)
|
||||
$(QUITE) $(RUN_POST_SCRIPT) sdk
|
||||
ifneq ($(PACK_SCRIPT),)
|
||||
$(info +PACK-FIRMWARE)
|
||||
$(QUITE) $(PACK_SCRIPT)
|
||||
endif
|
||||
|
||||
pack:
|
||||
$(info +PACK-FIRMWARE)
|
||||
ifneq ($(PACK_SCRIPT),)
|
||||
$(QUITE) $(PACK_SCRIPT)
|
||||
else
|
||||
$(error pack script is Windows-only)
|
||||
endif
|
||||
|
||||
pre_build:
|
||||
$(info +PRE-BUILD)
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
@echo off
|
||||
chcp 65001 >nul
|
||||
cd /d "%~dp0"
|
||||
setlocal EnableDelayedExpansion
|
||||
|
||||
REM JieLi make / mkdir_win / rm / fixbat live in tools\utils, not in system PATH
|
||||
set "PATH=%~dp0tools\utils;%PATH%"
|
||||
|
||||
REM USB burn: default WITH key. build.bat nokey to burn without key
|
||||
set "JL_BURN_KEY=1"
|
||||
set "MAKE_ARGS="
|
||||
|
||||
for %%A in (%*) do (
|
||||
if /i "%%~A"=="key" (
|
||||
set "JL_BURN_KEY=1"
|
||||
) else if /i "%%~A"=="nokey" (
|
||||
set "JL_BURN_KEY=0"
|
||||
) else (
|
||||
set "MAKE_ARGS=!MAKE_ARGS! %%~A"
|
||||
)
|
||||
)
|
||||
|
||||
if "!JL_BURN_KEY!"=="1" (
|
||||
echo [build] USB burn: WITH key
|
||||
) else (
|
||||
echo [build] USB burn: NO key
|
||||
)
|
||||
|
||||
make !MAKE_ARGS!
|
||||
exit /b !errorlevel!
|
||||
@@ -10,10 +10,67 @@ copy ..\..\ota.bin .
|
||||
copy ..\..\anc_coeff.bin .
|
||||
copy ..\..\anc_gains.bin .
|
||||
|
||||
..\..\isd_download.exe ..\..\isd_config.ini -tonorflash -dev br28 -boot 0x120000 -div8 -wait 300 -uboot ..\..\uboot.boot -app ..\..\app.bin -res ..\..\cfg_tool.bin tone.cfg p11_code.bin -uboot_compress -key RS-5B88.key
|
||||
set "ISD_CMD=..\..\isd_download.exe ..\..\isd_config.ini -dev br28 -boot 0x120000 -div8 -wait 300 -uboot ..\..\uboot.boot -app ..\..\app.bin -res ..\..\cfg_tool.bin tone.cfg p11_code.bin -uboot_compress"
|
||||
|
||||
:: -format all -key RS-5B88.key
|
||||
::-reboot 2500
|
||||
REM JL_BURN_KEY=1/key : USB flash keyed image; still generate nokey files
|
||||
REM default / 0 / nokey : USB flash nokey image; still generate keyed files
|
||||
set "NOKEY_FLASH="
|
||||
set "KEY_FLASH="
|
||||
if /i "%JL_BURN_KEY%"=="1" goto :usb_key
|
||||
if /i "%JL_BURN_KEY%"=="key" goto :usb_key
|
||||
if /i "%JL_BURN_KEY%"=="yes" goto :usb_key
|
||||
set "NOKEY_FLASH=-tonorflash"
|
||||
echo [download] USB burn: NO key
|
||||
goto :do_isd
|
||||
|
||||
:usb_key
|
||||
set "KEY_FLASH=-tonorflash"
|
||||
echo [download] USB burn: WITH key
|
||||
|
||||
:do_isd
|
||||
REM ---- nokey image ----
|
||||
%ISD_CMD% %NOKEY_FLASH%
|
||||
if exist jl_isd.fw copy /y jl_isd.fw jl_isd_nokey.fw >nul
|
||||
..\..\ufw_maker.exe -fw_to_ufw jl_isd.fw
|
||||
if exist jl_isd.ufw (
|
||||
copy /y jl_isd.ufw update.ufw >nul
|
||||
copy /y jl_isd.ufw update_nokey.ufw >nul
|
||||
del jl_isd.ufw
|
||||
)
|
||||
if exist db_update_data.bin copy /y db_update_data.bin db_update_data_nokey.bin >nul
|
||||
|
||||
REM ---- keyed image ----
|
||||
if exist RS-5B88.key (
|
||||
%ISD_CMD% %KEY_FLASH% -key RS-5B88.key
|
||||
REM isd_download returns -11 when USB is offline; image is still generated
|
||||
if exist jl_isd.fw copy /y jl_isd.fw jl_isd_key.fw >nul
|
||||
..\..\ufw_maker.exe -fw_to_ufw jl_isd.fw
|
||||
if exist jl_isd.ufw (
|
||||
copy /y jl_isd.ufw update_key.ufw >nul
|
||||
del jl_isd.ufw
|
||||
)
|
||||
if exist db_update_data.bin copy /y db_update_data.bin db_update_data_key.bin >nul
|
||||
) else (
|
||||
if /i not "%KEY_FLASH%"=="" (
|
||||
echo [download] ERROR: RS-5B88.key not found, cannot USB-burn keyed image
|
||||
exit /b 1
|
||||
)
|
||||
)
|
||||
|
||||
REM default burn image name: keyed (unless explicitly 0/nokey). Tools that look for
|
||||
REM jl_isd.fw / update.ufw get the keyed image by default.
|
||||
if /i "%JL_BURN_KEY%"=="0" goto :dflt_nokey
|
||||
if /i "%JL_BURN_KEY%"=="nokey" goto :dflt_nokey
|
||||
REM default / 1 / key / yes / empty -> keyed as default name
|
||||
if exist jl_isd_key.fw copy /y jl_isd_key.fw jl_isd.fw >nul
|
||||
if exist update_key.ufw copy /y update_key.ufw update.ufw >nul
|
||||
if exist db_update_data_key.bin copy /y db_update_data_key.bin db_update_data.bin >nul
|
||||
goto :dflt_end
|
||||
:dflt_nokey
|
||||
if exist jl_isd_nokey.fw copy /y jl_isd_nokey.fw jl_isd.fw >nul
|
||||
if exist update_nokey.ufw copy /y update_nokey.ufw update.ufw >nul
|
||||
if exist db_update_data_nokey.bin copy /y db_update_data_nokey.bin db_update_data.bin >nul
|
||||
:dflt_end
|
||||
|
||||
@rem delete temp files
|
||||
if exist *.mp3 del *.mp3
|
||||
@@ -22,15 +79,6 @@ if exist *.TAB del *.TAB
|
||||
if exist *.res del *.res
|
||||
if exist *.sty del *.sty
|
||||
|
||||
..\..\ufw_maker.exe -fw_to_ufw jl_isd.fw
|
||||
copy jl_isd.ufw update.ufw
|
||||
del jl_isd.ufw
|
||||
|
||||
@rem generate config ufw (disabled)
|
||||
::ufw_maker.exe -chip AC800X %ADD_KEY% -output config.ufw -res bt_cfg.cfg
|
||||
|
||||
::IF EXIST jl_696x.bin del jl_696x.bin
|
||||
|
||||
if exist script.ver del script.ver
|
||||
if exist tone.cfg del tone.cfg
|
||||
if exist p11_code.bin del p11_code.bin
|
||||
@@ -39,9 +87,9 @@ if exist anc_coeff.bin del anc_coeff.bin
|
||||
if exist anc_gains.bin del anc_gains.bin
|
||||
|
||||
@rem common isd_download flags
|
||||
@rem -format vm
|
||||
@rem -format cfg
|
||||
@rem -format 0x3f0-2
|
||||
@rem -format vm erase VM area
|
||||
@rem -format cfg erase BT CFG area
|
||||
@rem -format 0x3f0-2 erase 2 sectors from 0x3f0 (1st arg hex/dec, 2nd must be decimal)
|
||||
|
||||
ping /n 2 127.1>null
|
||||
IF EXIST null del null
|
||||
IF EXIST null del null
|
||||
|
||||
@@ -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
|
||||
@@ -0,0 +1,168 @@
|
||||
# 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:
|
||||
# .\build.bat - build + download.bat + pack
|
||||
# make pack - pack only
|
||||
# tools\pack_firmware.bat
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string]$ProjectName = "PTHFAN",
|
||||
[string]$SdkRoot = ""
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$exitCode = 0
|
||||
|
||||
try {
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($SdkRoot)) {
|
||||
$SdkRoot = Split-Path -Parent $PSScriptRoot
|
||||
}
|
||||
|
||||
$VersionHeader = Join-Path $SdkRoot "apps\usr_jb_proto\Protocol\jb_product.h"
|
||||
$DownloadDir = Join-Path $SdkRoot "cpu\br28\tools\download\earphone"
|
||||
$ReleaseRoot = Join-Path $SdkRoot "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+JB_MCU_SW_VERSION_MAJOR\s+(\d+)') {
|
||||
$major = $Matches[1]
|
||||
}
|
||||
if ($text -match '(?m)^\s*#define\s+JB_MCU_SW_VERSION_MINOR\s+(\d+)') {
|
||||
$minor = $Matches[1]
|
||||
}
|
||||
if ($text -match '(?m)^\s*#define\s+JB_MCU_SW_VERSION_PATCH\s+(\d+)') {
|
||||
$patch = $Matches[1]
|
||||
}
|
||||
|
||||
if (($null -eq $major) -or ($null -eq $minor) -or ($null -eq $patch)) {
|
||||
throw "cannot parse JB_MCU_SW_VERSION_* 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 "yyMMddHHmm"
|
||||
$pkgName = "${ProjectName}_${version}_${dateStr}"
|
||||
|
||||
Write-Host "project : $ProjectName"
|
||||
Write-Host "version : $version (from jb_product.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
|
||||
@@ -0,0 +1,6 @@
|
||||
burner_nokey|不带 Key:产线批量烧录器镜像(调试、未加密芯片)
|
||||
app_nokey|不带 Key:手机 APP / 小程序 OTA(UFW)
|
||||
gw_nokey|不带 Key:55AA 服务器 OTA / 网关 OTA(杰理双备份包)
|
||||
burner_key|带 Key:产线批量烧录器镜像(烧录器需配置同一把 key)
|
||||
app_key|带 Key:手机 APP / 小程序 OTA(UFW)
|
||||
gw_key|带 Key:55AA 服务器 OTA / 网关 OTA(杰理双备份包)
|
||||
@@ -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=0x02(BLE),不要传 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。两套文件都会打包。
|
||||
Reference in New Issue
Block a user