# -*- coding: utf-8 -*- """ log_decode.py — 将 K1 LOG.BIN(W25Q 日志分区镜像)解码为可读时间线 布局: [0x0000 .. 0x0FFF] header (magic K1LG ...) [0x1000 .. end] 文本环形区,行以 \\n 结束 用法: python log_decode.py LOG.BIN -o problem.log python log_decode.py LOG.BIN --write-off 1234 --wrap 1 -o problem.log """ from __future__ import annotations import argparse import struct MAGIC = 0x4B314C47 # 'K1LG' HDR_SIZE = 0x1000 def unpack_header(blob: bytes) -> dict: if len(blob) < 36: return {"valid": False} magic = struct.unpack_from(" str: """Linearize ring: if wrapped, [write_off..end) + [0..write_off); else [0..write_off).""" if not data: return "" if write_off > len(data): write_off = len(data) if wrapped and write_off < len(data): raw = data[write_off:] + data[:write_off] else: raw = data[:write_off] if write_off else data text = raw.decode("utf-8", errors="replace") text = text.replace("\xff", "") return text def decode_file(bin_path: str, out_path: str, write_off=None, wrap_count=None) -> None: with open(bin_path, "rb") as f: blob = f.read() hdr = unpack_header(blob) data = blob[HDR_SIZE:] if len(blob) > HDR_SIZE else b"" wo = write_off if write_off is not None else hdr.get("write_off", 0) wrap = wrap_count if wrap_count is not None else hdr.get("wrap_count", 0) text = extract_text(data, wo, wrap > 0) lines = [ln for ln in text.splitlines() if ln.strip()] with open(out_path, "w", encoding="utf-8", newline="\n") as f: f.write( f"# K1 log decode magic_ok={hdr.get('valid')} ver={hdr.get('ver')} " f"boot={hdr.get('boot_count')} write_off={wo} wrap={wrap} " f"line_count={hdr.get('line_count')} decoded_lines={len(lines)}\n" ) for ln in lines: f.write(ln.rstrip("\r") + "\n") print(f"decoded {len(lines)} lines -> {out_path}") def main(): ap = argparse.ArgumentParser() ap.add_argument("bin") ap.add_argument("-o", "--out", default="problem.log") ap.add_argument("--write-off", type=int, default=None) ap.add_argument("--wrap", type=int, default=None) args = ap.parse_args() decode_file(args.bin, args.out, args.write_off, args.wrap) if __name__ == "__main__": main()