K1Guitar/tools/k1_harness/suites/keys_tm1617.py

100 lines
3.5 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
"""keys1617 套件TM1617 段落/导航键注入RTT `tm1617 key N`.
键值0=KEY_MAIN_D 1=KEY_MAIN_C 2=KEY_MAIN_B 3=KEY_MAIN_A 4=释放(KEY_NULL)
每个键单独开 RTT 会话失败时硬件复位后重试一次避免触摸洪泛饿死后续命令
"""
from __future__ import annotations
import os
import subprocess
import sys
import time
from ..paths import TOOLS_DIR
from ..transports.rtt_session import open_session
SUITE = "keys1617"
KEY_NAMES = {0: "MAIN_D", 1: "MAIN_C", 2: "MAIN_B", 3: "MAIN_A"}
def _hw_reset(device: str) -> None:
script = os.path.join(TOOLS_DIR, "rtt_reset.py")
subprocess.run(
[sys.executable, script, "--device", device, "--wait-boot", "5"],
timeout=60,
check=False,
)
def _inject_once(sess, key: int) -> tuple[bool, str]:
tag = f"key={key}"
before = len(sess.lines)
ok = sess.cmd_ack(f"tm1617 key {key}", "TM1617_KEY_OK", timeout_s=2.5, retries=3)
if ok:
return True, "TM1617_KEY_OK"
recent = sess.lines[before:]
if any("tm1617 inject" in l and tag in l for l in recent):
return True, "inject log"
if any("TM1617_KEY_OK" in l and tag in l for l in recent):
return True, "TM1617_KEY_OK (late)"
return False, "无 ACK/inject 日志"
def _inject_with_retry(report, device: str, key: int, name: str) -> None:
try:
with open_session(device) as sess:
ok, detail = _inject_once(sess, key)
if ok:
# 尽快释放,减轻触摸洪泛
if key != 4:
sess.cmd_ack("tm1617 key 4", "TM1617_KEY_OK", timeout_s=1.5, retries=2)
time.sleep(0.3)
report.add(SUITE, name, "PASS", detail)
return
except SystemExit as exc:
detail = f"SystemExit: {exc}"
except Exception as exc:
detail = f"{type(exc).__name__}: {exc}"
print(f"!! {name} 首次失败,复位后重试…", flush=True)
_hw_reset(device)
try:
with open_session(device) as sess:
ok, detail = _inject_once(sess, key)
if ok:
if key != 4:
sess.cmd_ack("tm1617 key 4", "TM1617_KEY_OK", timeout_s=1.5, retries=2)
report.add(SUITE, name, "PASS", detail + " (retry)")
return
report.add(SUITE, name, "FAIL", detail)
except SystemExit as exc:
report.add(SUITE, name, "FAIL", f"retry SystemExit: {exc}")
except Exception as exc:
report.add(SUITE, name, "FAIL", f"retry {type(exc).__name__}: {exc}")
def run(report, ctx) -> None:
# 探测命令是否存在
try:
with open_session(ctx.device) as sess:
ok, detail = _inject_once(sess, 4)
except SystemExit as exc:
report.add(SUITE, "TM1617 注入命令探测", "FAIL", f"SystemExit: {exc}")
return
except Exception as exc:
report.add(SUITE, "TM1617 注入命令探测", "FAIL", f"{type(exc).__name__}: {exc}")
return
if not ok:
report.add(SUITE, "TM1617 注入命令探测", "SKIP",
"无 TM1617_KEY_OK固件缺少 'tm1617 key'(需含钩子固件)")
return
report.add(SUITE, "TM1617 注入命令探测", "PASS", detail)
for key, label in KEY_NAMES.items():
_inject_with_retry(report, ctx.device, key, f"tm1617 {label}")
_hw_reset(ctx.device) # 每键后复位,保证下一键 RTT 干净
_inject_with_retry(report, ctx.device, 4, "tm1617 释放(KEY_NULL)")