Files
HW-Debug-Tools/HDMI-Tool/src/selftest_rs485.py
T

78 lines
2.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""dlpc_rs485 协议自检(无硬件): 对照上游 protocols.md 的实测帧向量做回归
用法: python selftest_rs485.py (全部通过退出码 0)
"""
import sys
import dlpc_rs485 as d
fails = []
def check(name, got, want):
ok = got == want
print(('PASS' if ok else 'FAIL'), name, '->', got, '' if ok else f'(期望 {want})')
if not ok:
fails.append(name)
# 1) 帧构造: protocols.md 实测示例 M730S0T2000
f = d.build_frame('M730S0T2000')
check('build_frame(M730S0T2000)', f.hex(' ').upper(),
'D5 01 0B 4D 37 33 30 53 30 54 32 30 30 30 8C')
# 2) 增量解析: ok 应答跨两个半包喂入
p = d.FrameParser()
r1 = p.feed(bytes.fromhex('B5 F0'))
r2 = p.feed(bytes.fromhex('02 6F 6B CC'))
check('split-feed frames', len(r1) + len(r2), 1)
fr = (r1 + r2)[0]
check('type_code', fr.type_code, 0xF0)
check('payload', fr.payload, 'ok')
check('describe(ok)', d.describe(fr), 'ok')
# 3) 前导噪声 + 0xFD err:OL 译码(字符串标记, 不附 DLPC 释义)
body = bytes.fromhex('FD 06 65 72 72 3A 4F 4C') # "err:OL"
good = bytes([0xB5]) + body + bytes([d.sum_crc(body)])
frames = d.FrameParser().feed(b'\x01\x02' + good)
check('noise+err-frame count', len(frames), 1)
check('describe(err:OL)', d.describe(frames[0]), '参数越界/读回复核不一致 err:OL')
# 4) 0xFA + 数字错误码 err:3 追加 DLPC 释义
body = bytes.fromhex('FA 05') + b'err:3'
fa = bytes([0xB5]) + body + bytes([d.sum_crc(body)])
frames = d.FrameParser().feed(fa)
check('describe(err:3)', d.describe(frames[0]),
'开光机通信失败 err:3(I2C NACK(器件无应答))')
# 5) CRC 坏帧被丢弃后继续同步到下一帧
bad = bytearray(good)
bad[-1] ^= 0xFF
frames = d.FrameParser().feed(bytes(bad) + good)
check('bad-crc then good', len(frames), 1)
check('recovered type', frames[0].type_code, 0xFD)
# 6) 非法输入拒绝
for bad_cmd in ('', ' '):
try:
d.build_frame(bad_cmd)
fails.append('empty-cmd-not-rejected')
except ValueError:
pass
try:
d.build_frame('M' * 40)
fails.append('long-cmd-not-rejected')
except ValueError:
pass
print('空/超长命令拒绝: PASS')
# 7) 预设命令全部可组帧
for _name, cmd, _note in d.PRESETS:
d.build_frame(cmd)
print(f'预设 {len(d.PRESETS)} 条全部可组帧: PASS')
print('RESULT:', 'FAIL:' + ','.join(fails) if fails else 'ALL PASS')
sys.exit(1 if fails else 0)