32 lines
1.7 KiB
Python
32 lines
1.7 KiB
Python
"""Package the application image for the platform's existing firmware upload flow."""
|
|||
|
|
import argparse
|
||
|
|
import hashlib
|
||
|
|
import json
|
||
|
|
from pathlib import Path
|
||
|
|
import re
|
||
|
|
import shutil
|
||
|
|
import struct
|
||
|
|
|
||
|
|
project = Path(__file__).resolve().parents[1]
|
||
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
||
|
|
parser.add_argument('--model', required=True, help='Exact inventory model, e.g. ECHOEAR-S3')
|
||
|
|
parser.add_argument('--app', type=Path, default=project / 'build/VolcRTCDemo.bin')
|
||
|
|
parser.add_argument('--out', type=Path, required=True)
|
||
|
|
args = parser.parse_args()
|
||
|
|
version = re.search(r'^#define DEVICE_FIRMWARE_VERSION "([^"]+)"', (project / 'main/firmware_version.h').read_text(), re.M).group(1)
|
||
|
|
image = args.app.read_bytes()
|
||
|
|
if not args.model or len(args.model.encode()) > 120:
|
||
|
|
parser.error('Model must match the device inventory and fit 120 bytes')
|
||
|
|
if not 1024 <= len(image) <= 4 * 1024 * 1024:
|
||
|
|
parser.error('The application must fit the 4 MiB OTA slot')
|
||
|
|
if image[0] != 0xE9 or struct.unpack_from('<H', image, 12)[0] != 9:
|
||
|
|
parser.error('Expected an ESP32-S3 application image')
|
||
|
|
if version.encode() + b'\0' not in image:
|
||
|
|
parser.error('Build is stale: compile the current firmware version first')
|
||
|
|
args.out.mkdir(parents=True, exist_ok=True)
|
||
|
|
output = args.out / f'echoear-{version}.bin'
|
||
|
|
shutil.copyfile(args.app, output)
|
||
|
|
manifest = {'model': args.model, 'version': version, 'size': len(image), 'sha256': hashlib.sha256(image).hexdigest(), 'file': output.name, 'max_ota_size': 4 * 1024 * 1024, 'upload_kind': 'application_only'}
|
||
|
|
(args.out / 'manifest.json').write_text(json.dumps(manifest, ensure_ascii=False, indent=2) + '\n', encoding='utf-8')
|
||
|
|
print(json.dumps(manifest, ensure_ascii=False))
|