Files
AMI/docs/evidence/2026-10-07/as-status-flash/153558/flash_as_v27.py
T

68 lines
4.0 KiB
Python

import hashlib,json,re,subprocess,threading,time
from datetime import datetime,timezone,timedelta
from pathlib import Path
import serial
R=Path('D:/YMR/AMI')
O=R/'docs/evidence/2026-10-07/as-status-flash'/datetime.now(timezone(timedelta(hours=8))).strftime('%H%M%S')
O.mkdir(parents=True)
CLI='D:/STM32CubeCLT_1.19.0/STM32CubeProgrammer/bin/STM32_Programmer_CLI.exe'
SN='37FF71064E573436188C1543'
binary=R/'output/firmware/AMI_Controller.bin';data=binary.read_bytes()
assert len(data)==16672 and hashlib.sha256(data).hexdigest()=='1951c63e779429d08a992d1171fc92173e4399307ff741fdc5d9b7646848855d'
report={'date':'2026-10-07','firmware':'v2.7','evidence_dir':str(O),'probe_serial':SN,'binary_bytes':len(data),'binary_sha256':hashlib.sha256(data).hexdigest(),'flash_verified':False,'full_readback_identical':False,'physical_can_test_performed':False,'physical_hmi_test_performed':False}
def run(name,args,mode='HOTPLUG'):
p=subprocess.run([CLI,'-c','port=SWD',f'sn={SN}','freq=1000',f'mode={mode}',*args],capture_output=True,timeout=45)
log=p.stdout+p.stderr;(O/(name+'.log')).write_bytes(log)
assert p.returncode==0,(name,log.decode(errors='replace'))
assert b'Device ID : 0x467' in log,(name,'unexpected target')
return log
report['target_probe']=run('target-probe',[]).decode(errors='replace')
assert 'Flash size : 128 KBytes' in report['target_probe']
backup=O/'before-flash-128k.bin'
run('before-flash-backup',['-u','0x08000000','131072',str(backup)])
assert backup.stat().st_size==131072
report['backup_bytes']=backup.stat().st_size;report['backup_sha256']=hashlib.sha256(backup.read_bytes()).hexdigest()
print('Backup complete: 128 KB',flush=True)
capture=bytearray();errors=[];stop=threading.Event();port=None;thread=None
try:
port=serial.Serial(port=None,baudrate=9600,timeout=.05)
port.port='COM6';port.dtr=False;port.rts=False;port.open()
def reader():
try:
while not stop.is_set():capture.extend(port.read(512))
except Exception as exc:errors.append(repr(exc))
thread=threading.Thread(target=reader);thread.start()
except Exception as exc:report['serial_open_error']=repr(exc)
try:
log=run('flash',['reset=HWrst','-w',str(binary),'0x08000000','-v','-rst'],'UR')
assert b'Download verified successfully' in log
report['flash_verified']=True
print('v2.7 programmed and verified',flush=True)
readback=O/'flash-readback-128k.bin'
run('flash-readback',['-u','0x08000000','131072',str(readback)])
assert readback.stat().st_size==131072
assert readback.read_bytes()[:len(data)]==data,'Flash image differs from published BIN'
report['full_readback_identical']=True
report['readback_image_sha256']=hashlib.sha256(readback.read_bytes()[:len(data)]).hexdigest()
report['readback_128k_sha256']=hashlib.sha256(readback.read_bytes()).hexdigest()
log=run('reset',['-rst']);assert b'reset is performed' in log.lower()
report['reset_performed']=True
time.sleep(8)
finally:
stop.set()
if thread:thread.join(timeout=2)
if port:port.close()
(O/'uart-com6.bin').write_bytes(capture)
commands=[];unknown=[]
for frame in bytes(capture).split(b'\xff\xff\xff'):
if not frame:continue
try:
command=frame.decode('ascii')
if re.fullmatch(r'(?:[A-Za-z_][A-Za-z_0-9]*\.){0,2}[A-Za-z_][A-Za-z_0-9]*=-?\d+',command):commands.append(command)
else:unknown.append(frame.hex(' '))
except UnicodeDecodeError:unknown.append(frame.hex(' '))
report['serial']={'port':'COM6','baudrate':9600,'captured_bytes':len(capture),'complete_commands':commands,'other_frames_hex':unknown,'errors':errors,'boot_unknown_uart_verified':all(c in commands for c in ['current_task=7','lock_state=0','ebs_state=0','as_state=6'])}
(O/'flash-and-uart-results.json').write_text(json.dumps(report,ensure_ascii=False,indent=2)+'\n',encoding='utf-8')
(R/'tmp/as-flash-evidence-path.txt').write_text(str(O),encoding='utf-8')
print(json.dumps(report,ensure_ascii=False,indent=2),flush=True)