fix(SerialMate): v0.1.2 解析模式不再吞数据——不成帧字节透传显示
背景: 用户接非 DLPilot 协议设备(COM25)开解析模式接收区一片空白——_dispatch_rx 在解析模式只上抛完整合法帧, 不成帧字节(纯文本日志/别的协议/波特率不符乱码)被 FrameParser 重同步时静默丢弃。用户明确定位: 首先是基础串口调试工具, 自定义协议解析是附加项, 附加能力不得影响本体功能。 修复: protocol.py FrameParser 丢弃字节累积进 garbage(新增 drain_garbage(), feed() 返回值不变); link.py 新增 on_garbage(data, ts) 回调, 每批无条件 drain(未接回调也不累积); main.py 把 on_garbage 并入 raw 事件与透传行同格式显示, 解析协议帧开关补 tooltip, 版本 0.1.2。半帧前缀扣留语义有意保留(可能补全成真帧, 至多扣一个前缀长度)。 自检: selftest 8b +10 项(纯文本全透出/噪声+帧+尾字节/坏CRC帧字节全透出/半帧头扣留补全), loop 3b +3 项, gui 5b +2 项; 全量 67+21+68 项 PASS; exe 已重建。README/AGENTS.md(不变量 5a) 同步。
This commit is contained in:
@@ -331,6 +331,9 @@ class FrameParser:
|
||||
"""增量字节流 -> 完整帧: 前缀令牌逐位对齐(帧头/字面量, ID 为通配) + LEN 定长
|
||||
+ CRC 校验; 任一处失配丢 1 字节重新同步。LEN 值经口径换算后即 payload 长度,
|
||||
负值视为伪帧头逐出 —— 伪帧头最多滞留一帧即被逐出重同步, 对调试工具可接受。
|
||||
丢弃字节不销毁: 累积进 self.garbage, 由上层 drain_garbage() 取走透出 ——
|
||||
本工具首先是串口助手, 协议解析是附加层, 不成帧的字节也必须可见。
|
||||
(仅匹配上前缀、还在等后续字节的"半帧"缓冲不算垃圾, 可能补全成真帧)
|
||||
"""
|
||||
|
||||
def __init__(self, cfg):
|
||||
@@ -349,9 +352,22 @@ class FrameParser:
|
||||
self._len_pos = lay.len_pos
|
||||
self._extra = lay.len_extra(cfg.len_sem, cs)
|
||||
self._buf = bytearray()
|
||||
self.garbage = bytearray() # 重同步丢弃的非帧字节(调用方定期取走)
|
||||
|
||||
def clear(self):
|
||||
self._buf.clear()
|
||||
self.garbage.clear()
|
||||
|
||||
def drain_garbage(self):
|
||||
"""取走累积的非帧字节(bytes)并清空; 解析模式不吞数据的取数入口"""
|
||||
out = bytes(self.garbage)
|
||||
self.garbage.clear()
|
||||
return out
|
||||
|
||||
def _drop_head(self):
|
||||
"""丢缓冲首字节重同步; 丢弃字节记入 garbage(可能正是用户要看的输出)"""
|
||||
self.garbage.append(self._buf[0])
|
||||
del self._buf[:1]
|
||||
|
||||
def _aligned(self):
|
||||
"""把缓冲对齐到前缀匹配; 字节不足且已匹配部分则保持等待(返回 True),
|
||||
@@ -365,7 +381,7 @@ class FrameParser:
|
||||
break # 失配 -> 丢 1 字节
|
||||
else:
|
||||
return True
|
||||
del buf[:1]
|
||||
self._drop_head()
|
||||
if not buf:
|
||||
return False
|
||||
|
||||
@@ -378,7 +394,7 @@ class FrameParser:
|
||||
break # LEN 字节未到齐
|
||||
plen = self._buf[self._len_pos] - self._extra
|
||||
if plen < 0: # LEN 为负 -> 伪帧头, 逐出重同步
|
||||
del self._buf[:1]
|
||||
self._drop_head()
|
||||
continue
|
||||
total = cfg.layout.total_size(plen, cfg.crc_size)
|
||||
if len(self._buf) < total:
|
||||
@@ -388,7 +404,7 @@ class FrameParser:
|
||||
frames.append(cfg.parse_frame(raw))
|
||||
del self._buf[:total]
|
||||
else:
|
||||
del self._buf[:1] # CRC 失配 -> 丢帧头重同步
|
||||
self._drop_head() # CRC 失配 -> 丢帧头重同步
|
||||
return frames
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user