Files
MeshCore/tools/hil/profile_four_tx_package.py
T

56 lines
3.0 KiB
Python

"""Package already-built bench artifacts locally, with exact DFU/image gates."""
import hashlib
import io
import json
from pathlib import Path
import subprocess
import zipfile
from intelhex import IntelHex
from profile_four_tx_fixture import TXS,RX
ROOT=Path(__file__).resolve().parents[2]
DEST=ROOT/'out'/'profile-four-tx-20260914'
DEST.mkdir(parents=True,exist_ok=True)
contents={}
manifest={'git_head':subprocess.check_output(['git','rev-parse','HEAD'],cwd=ROOT,text=True).strip(),
'scope':'Dirty-worktree HIL artifacts; four physical fixed-channel TXs and one fast single-pass RX',
'targets':TXS,'receiver':RX,'files':{}}
def add(name,data):
if name in contents: raise ValueError('Duplicate artifact')
contents[name]=data
manifest['files'][name]={'bytes':len(data),'sha256':hashlib.sha256(data).hexdigest()}
for t in TXS:
build=ROOT/'.pio/build'/t['env']
payload=(build/'firmware.zip').read_bytes()
with zipfile.ZipFile(io.BytesIO(payload)) as z:
m=json.loads(z.read('manifest.json'))['manifest']
if set(m)!={'application','dfu_version'}: raise ValueError('Not application-only DFU')
app=m['application']
if app['init_packet_data']['softdevice_req']!=[t['fwid']]: raise ValueError('Wrong SoftDevice requirement')
binary=z.read(app['bin_file'])
if len(binary)>0xED000-t['app_base']: raise ValueError('Image exceeds safe application range')
image=IntelHex(str(build/'firmware.hex'))
addresses=image.addresses()
if min(addresses)!=t['app_base'] or max(addresses)>=0xED000: raise ValueError('HEX writes outside application')
if bytes(image.tobinarray())!=binary:raise ValueError('DFU binary disagrees with linked application')
add(t['env']+'.zip',payload)
manifest['files'][t['env']+'.zip'].update(app_base=min(addresses),image_end=max(addresses)+1,fwid=t['fwid'])
for name in ('firmware.bin','partitions.bin','bootloader.bin'):
add('rx-'+name,(ROOT/'.pio/build'/RX['env']/name).read_bytes())
add('rx-boot_app0.bin',(Path.home()/'.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin').read_bytes())
for name in ('profile_four_tx_fixture.py','profile_four_tx_deploy.py','profile_four_tx.py',
'profile_switch.py','serial_session.py','profile_switch_channels.py','profile_switch_packets.py',
'profile_switch_sweep.py'):
add(name,(ROOT/'tools/hil'/name).read_bytes())
for name in ('profile_fixed_tx.cpp','profile_fixed_tx.ini','profile_switch.cpp','profile_switch_channels.h',
'ProfileChannelTrace.h','ProfileFrequencyOffset.h'):
add(name,(ROOT/'tools/hil'/name).read_bytes())
with zipfile.ZipFile(DEST/'bundle.zip','x',zipfile.ZIP_DEFLATED) as z:
for name,data in contents.items():z.writestr(name,data)
z.writestr('manifest.json',json.dumps(manifest,indent=2))
(DEST/'manifest.json').write_text(json.dumps(manifest,indent=2)+'\n')
print(json.dumps({'bundle':str(DEST/'bundle.zip'),'sha256':hashlib.sha256((DEST/'bundle.zip').read_bytes()).hexdigest(),
'files':manifest['files']},indent=2))