串口窗口里出现过一次 OK,过了几分钟,还能说清它属于哪次操作吗?如果后面又出现错误,之前的成功提示还算不算数?

阅读开源项目 MCUscope 后,我给本站的串口调试台增加了一组围绕“一次实验”的功能:命名会话、事件标记、数值曲线,以及结束时的日志条件检查。打开工具,点击“体验会话与曲线”,不接硬件就能查看效果。

这些功能思路和 !p、!m 文本格式来自 MCUscope;浏览器实现由本站独立编写,没有复制其源代码,也没有集成它的后台服务。下文会说明本次借鉴的范围,以及实际使用时应该如何理解结果。

MCUscope 带来的启发

MCUscope 由 dwatman 维护,采用 MIT 许可。它让后台进程统一持有串口,把日志存入 SQLite,再通过网页和 CLI 查询、控制。命名会话能够圈定一次测试,标记记录操作时刻,wait 和 assert 则把输出转换成可供脚本使用的结果。

其中最有启发的是记录方式:原始输出之外,还应该知道测试的起止、人的操作,以及判断依据。日志可以继续滚动,但一次实验需要有明确边界。

本站工具使用浏览器直接连接串口。它适合临时调试与短时观察;需要脱离网页持续采集、数据库检索或 CLI 自动化时,MCUscope 的架构更合适。

这一版增加了什么

功能 本站的使用方式
测试会话 给本轮观察起名,开始后接收数据,手动结束并检查
事件标记 点击记录操作,也能识别设备输出的 !m 行
数值曲线 识别 !p 文本,选择通道查看,导出 CSV
日志条件 填写必须出现、禁止出现的文本,结束时生成结果
会话报告 导出 JSON,包含条件、命中情况、保留的接收行、标记、曲线与缺口

原有文本与 HEX 收发、过滤、快捷命令、本地文件自动保存仍可使用。新会话独立记录接收行,因此清空终端、隐藏日志或暂停终端画面,都不会改变本轮检查的输入。曲线和会话状态继续更新,终端的“暂停画面”只作用于终端。

用一次自检熟悉流程

假设设备有一个已有的自检命令,完成时会打印 SELFTEST OK,严重错误会打印 PANIC。这是演示约定,具体命令和日志必须以自己的固件为准。

  1. 连接串口,填写会话名称,例如“自检第 1 次”。
  2. 在“必须出现”填写 SELFTEST OK,在“禁止出现”填写 PANIC。
  3. 点击“开始会话”。此时固定本轮条件,只接收开始后的数据。
  4. 使用原有发送区手动发送设备支持的命令,或按硬件按键。
  5. 可添加“按下按键”等事件标记;观察足够时间后点击“结束并检查”。
  6. 导出会话 JSON,再开始下一轮。页面只保留最近一次会话。

开始、结束与标记按钮只操作本地记录,不向设备发送命令。不存在自动重试:命令写入完成后,仍要看设备的实际应答。

规则采用区分大小写的纯文本包含匹配,每行一条,每类最多 20 条。多条必须出现条件需要全部命中;任一禁止条件命中就失败。例如 ERROR|PANIC 在这里表示一段包含竖线的普通文本,要检查两个词,应当分两行填写。为了让规则容易理解,本版没有加入正则表达式。

条件只检查完整 RX 行,不检查 TX,也不检查手动标记。设备如果把命令原样回显,回显仍属于 RX;因此不宜把发送的命令本身当作成功条件,应选择能区分实际结果的应答内容。

用普通文本绘制数值曲线

在会话开始后,设备输出如下文本即可生成两个通道:

1
2
3
!p 1000 temperature=25.6 battery=3.12
!p 1100 temperature=25.8 battery=3.11
!p 1200 temperature=25.7 battery=3.10

这里沿用 MCUscope 的 !p 格式:毫秒计数之后是一组名称与数值。本版支持有限数值的整数、小数和科学计数法;通道名以 ASCII 字母或下划线开头,后续可以包含数字、点、下划线和短横线,最多 32 个字符。设备毫秒计数必须是非负安全整数。

MCU 不一定需要浮点 printf。例如电池电压以整数毫伏保存,可以自行输出整数部分和三位小数。只有实际固件提供了这些测量值,曲线才有相应物理意义。

横轴使用设备提供的毫秒计数。计数回退时会建立新段,当前通道只绘制最后一段,避免跨复位或计数回绕画出连续线。CSV 同时保存分段编号、设备计数和浏览器接收时间;它们不是同一种时钟。浏览器接收时间也不是精密采样时间。

本版不支持 MCUscope 的 typed streams、数字/枚举泳道、CAN 解码或设备 monitor 命令协议。!p 与 !m 只是明确列出的文本子集,不代表完整协议兼容。

给操作留下标记

手动标记适合写下“调整负载”“按键一次”“遮挡传感器”等现场动作。设备也可以发出:

1
2
!m @1200 selftest finished
!m button pressed

@1200 是可选的设备计数。标记列表显示浏览器接收时间,并区分手动与设备来源;设备计数保留在列表和报告中。标记当前以列表展示,不叠加到曲线横轴。

手动标记不会进入日志条件检查,避免把自己写的“自检成功”当作设备真的成功。设备标记是实际接收行,仍会参与 RX 文本检查。

为什么要等到结束才判断

“必须出现”的文本已经命中,并不表示接下来不会出现禁止文本。因此观察过程中只显示命中数,结论要等会话结束。

状态 含义
观察中 会话仍在接收,不给最终通过结论
通过 有非空完整接收行、条件全部满足,且未记录妨碍判断的缺口
失败 禁止文本出现,或证据完整但缺少必须出现的文本
证据不完整 没有有效输入,或出现接收错误、截断、淘汰等缺口,无法判定通过
未配置检查条件 只记录,不给通过或失败结论

即使有其他缺口,已经收到的禁止文本仍会导致失败,并在报告中保留缺口。这个结果只解释所填的文本条件;日志命中不能代替设备行为、功耗、时序或场景性能的验证。

为避免浏览器后台运行被误认为完整观察,切换到后台会结束当前测试会话,并标记证据不完整;已有串口接收和文件保存沿用原有行为。断开同样结束会话。需要跨窗口长期值守时,应使用有后台采集进程的工具。

记录容量与导出边界

网页为各类数据设置独立上限:

  • 会话接收文本:最近 2,000 行,且总计不超过 1 Mi 字符。
  • 标记:最近 100 条。
  • 数值曲线:前 8 个通道,每个保留最近 600 点。
  • 单行:最多 16 KiB 原始字节、解码后最多 4,096 字符,超过会跳过并记录缺口。

接收行淘汰后,即使此前出现过所有成功词,也不再给“通过”。曲线点或标记淘汰独立计数,不直接改变接收文本检查;导出时只能取得仍然保留的数据。JSON 包含规则、缺口和各类计数,CSV 只包含保留的曲线样本。

会话保存在当前页面内存,不写入浏览器数据库,也不上传。需要长期原始记录时,可以另外启用已有的本地文件自动保存;它与会话报告是两份不同用途的记录。刷新或关闭页面前请导出会话。

实现与验证

实现分为独立会话核心与界面接入。会话核心直接处理真实接收字节,在完整行边界解码和判断;它不读取经过筛选或美化后的终端 DOM。跨会话的残余半行会跳过并记录缺口,避免旧数据混入新一轮。

验证覆盖跨块 UTF-8、CRLF、旧半行、迟到的禁止文本、空输入、解码错误、容量淘汰、设备计数回退以及导出结构。浏览器交互测试使用模拟 Web Serial,检查会话不发送命令、显示操作不改变结果、断线与读取告警、来源链接和不同屏宽布局。这些属于软件与模拟验证,本轮没有进行真实串口硬件验收。

后续如果增加定时观察、更多曲线或报告回放,应继续沿用这条原则:把数据来源、观察窗口和缺口一并交给使用者。

来源与致谢

感谢 Daniel Watman(dwatman)公开 MCUscope 的设计与实现。本次借鉴会话、标记、日志断言的组织方式及 !p / !m 文本约定,采用独立的浏览器实现。工具页面与源码入口同时保留出处说明。