summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZixun LI <[email protected]>2026-07-27 14:39:20 +0200
committerZixun LI <[email protected]>2026-07-27 14:39:20 +0200
commit80ffbff6e98a9c5053bba008ae2c5087f0351300 (patch)
treec89ca85452956e17c87ef52ee06dc60b0e982575
parenta2f4786865e85f9cfe7f58c86fbb9355bbd2d701 (diff)
test/hil: separate LPC43 stress test flashes
-rw-r--r--test/hil/hfp.json6
-rwxr-xr-xtest/hil/hil_test.py62
2 files changed, 59 insertions, 9 deletions
diff --git a/test/hil/hfp.json b/test/hil/hfp.json
index 735d5a402..17fbb7605 100644
--- a/test/hil/hfp.json
+++ b/test/hil/hfp.json
@@ -36,7 +36,11 @@
"flasher": {
"name": "jlink",
"uid": "728973776",
- "args": "-device LPC43S67_M4"
+ "args": "-device LPC43S67_M4",
+ "pre_flash": {
+ "device/usbtest": "device/board_test",
+ "device/cdc_msc_throughput": "device/board_test"
+ }
}
}
]
diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py
index 0efc6826f..72af6c697 100755
--- a/test/hil/hil_test.py
+++ b/test/hil/hil_test.py
@@ -321,6 +321,7 @@ class FlasherCfg(TypedDict):
name: str
uid: str
args: str
+ pre_flash: NotRequired[dict[str, str]] # target example -> USB-off separator example
class AttachedDevCfg(TypedDict, total=False):
@@ -1830,6 +1831,19 @@ def find_firmware(variant: str, example: str):
return None
+def usb_uid_paths(uid: str) -> set[str]:
+ """Return sysfs device paths currently exposing the requested USB serial."""
+ paths = set()
+ for f in glob.glob('/sys/bus/usb/devices/*/serial'):
+ try:
+ with open(f) as serial_file:
+ if serial_file.read().strip().lower() == uid.lower():
+ paths.add(os.path.dirname(f))
+ except OSError:
+ pass
+ return paths
+
+
def test_example(board: Board, variant: str, example: str) -> tuple[int, str, str | None]:
"""
Test example firmware
@@ -1852,7 +1866,16 @@ def test_example(board: Board, variant: str, example: str) -> tuple[int, str, st
log_line(f'{test_name} Skip (no binary)')
return 0, 'skip', None
+ pre_flash_example = None if skip_flash else board['flasher'].get('pre_flash', {}).get(example)
+ pre_flash_name = find_firmware(variant, pre_flash_example) if pre_flash_example else None
+ if pre_flash_example and pre_flash_name is None:
+ log_line(f'{test_name} {STATUS_FAILED}: '
+ f'pre-flash firmware {pre_flash_example} not found')
+ return 1, 'fail', None
+
if verbose:
+ if pre_flash_name is not None:
+ log_line(f'Pre-flashing {pre_flash_name}.elf')
log_line(f'Flashing {fw_name}.elf')
# flash firmware (unless --skip-flash), then run the test. Both may fail randomly,
@@ -1867,13 +1890,36 @@ def test_example(board: Board, variant: str, example: str) -> tuple[int, str, st
attempt_out = io.StringIO()
with redirect_stdout(attempt_out):
if not skip_flash:
+ flash_ok = True
+ flash_error = ''
with flash_permit(board['uid']):
- t_flash = time.monotonic()
- ret = globals()[f'flash_{board["flasher"]["name"].lower()}'](board, str(fw_name))
- if PROFILE:
- log_line(f'[prof] {variant} {example} flash attempt {i + 1}: '
- f'{time.monotonic() - t_flash:.1f}s rc={ret.returncode}')
- flash_ok = (ret.returncode == 0)
+ if pre_flash_name is not None:
+ previous_usb_paths = usb_uid_paths(board['uid'])
+ ret = globals()[f'flash_{board["flasher"]["name"].lower()}'](
+ board, str(pre_flash_name))
+ flash_ok = (ret.returncode == 0)
+ if not flash_ok:
+ flash_error = f'Pre-flash {pre_flash_example} failed'
+ elif previous_usb_paths:
+ disconnected = wait_until(
+ lambda: all(not os.path.exists(p) for p in previous_usb_paths), step=0.1)
+ if not disconnected:
+ flash_ok = False
+ flash_error = (f'Pre-flash {pre_flash_example} did not disconnect '
+ f'USB device {board["uid"]}')
+ else:
+ time.sleep(0.1)
+
+ if flash_ok:
+ t_flash = time.monotonic()
+ ret = globals()[f'flash_{board["flasher"]["name"].lower()}'](
+ board, str(fw_name))
+ if PROFILE:
+ log_line(f'[prof] {variant} {example} flash attempt {i + 1}: '
+ f'{time.monotonic() - t_flash:.1f}s rc={ret.returncode}')
+ flash_ok = (ret.returncode == 0)
+ if not flash_ok:
+ flash_error = 'Flash failed'
if flash_ok:
try:
tret = globals()[f'test_{example.replace("/", "_")}'](board)
@@ -1911,10 +1957,10 @@ def test_example(board: Board, variant: str, example: str) -> tuple[int, str, st
log_line(msg)
time.sleep(0.5)
else:
- last_err = 'Flash failed'
+ last_err = flash_error
last_detail = compact_output(attempt_out.getvalue())
if i < max_retry - 1:
- msg = f'{test_name} retry {i+2}/{max_retry}: flash failed'
+ msg = f'{test_name} retry {i+2}/{max_retry}: {flash_error}'
if last_detail:
msg += f' {last_detail}'
log_line(msg)