107 lines
5.6 KiB
Markdown
107 lines
5.6 KiB
Markdown
# 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` 等)—— 适合脚本化/一次性抓取
|
||
- **串口端口单一配置源:`.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)→ 再烧录触发复位 → 采集自动抓取。**
|
||
|
||
```powershell
|
||
# 一键:采集(含 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)
|
||
|
||
用于主动下发命令、读取响应(非开机日志抓取):
|
||
|
||
1. `serial_list_ports` → 找 `COM6`(读 `.opencode/serial_config.json` 确认)
|
||
2. `serial_open`(port=COM6, baud_rate=115200)→ 返回 `connection_id`(UUID)
|
||
3. `serial_write`(connection_id, data, encoding=utf8/hex/base64)
|
||
4. `serial_read`(connection_id, timeout_ms=1000)→ 单次读,只能读到调用后的字节
|
||
5. `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 与文档已全部清理。
|