5.6 KiB
5.6 KiB
serial-mcp-server 串口调试指南
通过 Adancurusul/serial-mcp-server(Rust,MIT)自主读取/控制 USART1 串口(PA9 TX / PA10 RX,115200bps)的打印流(MCU printf)。
项目与安装
- 仓库:https://github.com/Adancurusul/serial-mcp-server
- 本机安装:
%LOCALAPPDATA%\serial-mcp-server\serial-mcp-server.exe(自源码cargo build --release编译,v0.3.0) - 两种形态:
- MCP stdio server(
serve子命令)—— opencode.json 中mcp.serial,工具带serial_前缀 - CLI(
list-ports/open/read/write/close等)—— 适合脚本化/一次性抓取
- MCP stdio server(
- 串口端口单一配置源:
.opencode/serial_config.json(当前本机COM6/ 115200)。端口变化只改这个文件
核心能力边界(重要)
⚠️ 该项目没有"读取历史消息/历史缓冲"功能(对比 qarnet/serial-mcp 有常驻环形缓冲):
- MCP
read只能读到调用之后到达的字节,之前的数据直接丢弃 - 连接打开期间没有后台 ring buffer(源码
src/serial/connection.rs只持有流,无历史) - 抓开机日志必须用 采集窗口模式(
duration_ms+start_trigger=first-byte):先启动采集等第一字节,再触发设备输出,否则错过
采集窗口模式(capture)
这是该项目抓完整连续输出的唯一方式,等价于"有边界的持续读"。
CLI 参数
serial-mcp-server read --port COM6 --baud 115200 \
--duration-ms 30000 \ # 采集窗口时长(从触发点起算)
--start-trigger first-byte \ # 触发方式:first-byte(默认)/ immediate
--initial-timeout-ms 90000 \ # first-byte 模式最多等多久来第一字节(超时空返回)
--idle-timeout-ms 8000 \ # 采集开始后连续静默多久提前结束
--max-bytes 65536 \ # 累计字节硬上限
--json
结束原因(completion_reason)
| 值 | 含义 |
|---|---|
initial_timeout |
等 first-byte 超时,返回空(不算错误) |
duration_elapsed |
从触发点采满 duration-ms |
idle_timeout |
采集中途静默超过 idle-timeout-ms 提前收工 |
max_bytes |
累计达 max-bytes |
返回结构
read 对象含:data(合并完整字节)、bytes_read、status(ok/timeout)、completion_reason、waited_ms(等到首字节耗时)、elapsed_ms(采集时长)、chunks[](每块 offset/bytes_read/waited_ms/elapsed_ms)。
抓取 MCU 开机日志(@test 核心场景)
顺序必须:先启动采集(打开 COM 等 first-byte)→ 再烧录触发复位 → 采集自动抓取。
# 一键:采集(含 EOF 重试)→ 烧录 → 提取日志 → verify 校验(在仓库根目录执行,路径用仓库相对路径)
powershell -ExecutionPolicy Bypass -File "test\run_boot_test.ps1" `
-Port COM6 -BaudRate 115200 -DurationMs 30000 -InitialTimeoutMs 90000 `
-IdleTimeoutMs 8000 -MaxBytes 65536 `
-FlashCmd "MDK-ARM\download.bat" `
-Required "App init OK;Network Init;net init: OK;PHY: 100M FULL" `
-Forbidden "FAIL;ERROR;HardFault"
退出码:0=PASS / 1=FAIL / 2=采集或烧录错误。
底层脚本(test/serial_capture.ps1)
-FlashCmd分支:一个调用内完成 稳定启动采集 → 烧录 → 等采集结束,避免工具调用间隔导致采集超时- EOF 自动重试:COM 被上一个进程释放后立即重开会报
UnexpectedEof: serial stream returned zero bytes during capture(tokio-serial 读 0 字节,第三方项目 capture.rs 视为致命错误)。脚本检测到后退避 1.5s 重开,最多 3 次 - 采集稳定启动判据:进程存活超过
-StabilityCheckMs(默认 1.5s)
参数经验值(本机固件)
| 参数 | 值 | 理由 |
|---|---|---|
idle-timeout-ms |
8000 | boot 阶段有自然静默间隙(defaultTask 与 netTask 之间约 3~4s),太小会在网络初始化前提前结束 |
initial-timeout-ms |
90000 | 容错:烧录编译+下载耗时可能 40s+,采集必须等得住 |
duration-ms |
30000 | 覆盖完整开机流程(boot ~5s + net init ~3s + FTP 延迟 7s) |
交互式调试(MCP)
用于主动下发命令、读取响应(非开机日志抓取):
serial_list_ports→ 找COM6(读.opencode/serial_config.json确认)serial_open(port=COM6, baud_rate=115200)→ 返回connection_id(UUID)serial_write(connection_id, data, encoding=utf8/hex/base64)serial_read(connection_id, timeout_ms=1000)→ 单次读,只能读到调用后的字节serial_close
MCP read 也支持采集窗口字段:duration_ms、start_trigger、initial_timeout_ms、idle_timeout_ms(传 duration_ms 即进入 capture 模式)。
常见陷阱
| 现象 | 原因/处理 |
|---|---|
UnexpectedEof: serial stream returned zero bytes |
COM 刚被释放立即重开(tokio-serial 读 0 字节)。用 serial_capture.ps1(含重试)或间隔几秒再开 |
抓到日志缺少 Network Init |
idle-timeout-ms 太小,在网络初始化前的静默间隙提前结束;调到 8000ms |
| 烧录后无数据 | 采集必须在烧录前启动;initial-timeout-ms 太短导致采集先超时 |
Error: Connection ID ... not found |
connection_id 是每次 open 生成的 UUID,读/写/关都要用它 |
| 端口被占用 | 先 serial_close 释放;Keil ST-Link 下载不占 COM,可并存 |
工具历史
本项目是 Serial Studio MCP 的替代方案(更轻量、无 GUI 依赖、无导出文件定位问题)。Serial Studio 相关配置、bridge 与文档已全部清理。