Embedded Debug MCP
Provides serial debugging for embedded Linux targets, enabling boot log capture, automatic login, crash detection, U-Boot interrupt, and hardware reset via MCP protocol.
README
Embedded Debug Skill v3.0
基于 Python 的串口监控工具,通过 Dev Host ser2net 连接 Rockchip 嵌入式目标板。单 socat 连接、多 Agent 隔离、按上电周期自动分割日志。
设计目标
- 单连接:仅一个 socat 进程连接 Dev Host ser2net — 所有串口 I/O 通过它多路复用
- 多 Agent 隔离:每个 Claude Code Agent 通过 Unix socket 独立交互串口,互不干扰
- 按周期日志:自动检测启动周期(U-Boot SPL)→ 切换日志;断开连接 → 结束周期。一次上电→掉电对应一个日志文件
- 状态栏不闪烁:带滞后的防抖状态切换;statusline 仅读取缓存文件(<10ms)
- 自动登录:识别启动完成(login 提示),自动发送配置的登录凭据
- 挂死检测:无输出超时 + 滞后判断 →
DUT-off状态 → Agent 状态栏反馈 - U-Boot 中断:检测 autoboot 倒计时 → 自动发送 Ctrl-C 停留在 U-Boot 提示符
- 全 Python:零 bash 依赖;hooks 通过
uv run python-script.py执行 - socat 桥接:socat 处理 PTY↔TCP,Python 处理日志、多路复用、模式检测
- 崩溃识别:Kernel panic/BUG/Oops 检测 → 通过状态栏告警
架构
Dev Host (ser2net)
│
TCP :2000
│
┌──────────▼──────────┐
│ 单个 socat 进程 │ (由 daemon 管理)
│ PTY ↔ TCP ser2net │
└──────────┬──────────┘
│ PTY
┌──────────▼──────────┐
│ SerialDaemon │
│ │
│ ┌────────────────┐ │
│ │ 模式引擎 │ │
│ │ • 启动检测 │ │
│ │ • autoboot │ │
│ │ • login 提示 │ │
│ │ • 内核崩溃 │ │
│ │ • 挂死检测 │ │
│ │ • shell 提示符 │ │
│ └───────┬────────┘ │
│ │ │
│ ┌───────▼────────┐ │
│ │ 日志管理器 │──┼──▶ boot-001_20260609_120000.log
│ │ 按周期切割 │ │ boot-002_20260609_143000.log
│ └────────────────┘ │ ...
│ │
│ ┌────────────────┐ │
│ │ Agent 服务器 │ │
│ │ Unix socket │ │
│ │ ┌──────┐┌────┐ │ │
│ │ │AgentA││AgB │ │ │
│ │ └──┬───┘└──┬─┘ │ │
│ │ │ 命令 │ │ │
│ │ ▼ ▼ │ │
│ │ 命令队列 │ │ (串行化)
│ │ 响应路由 │ │ (按标记 ID)
│ └────────────────┘ │
│ │
│ ┌────────────────┐ │
│ │ 状态管理器 │──┼──▶ target-state 文件
│ │ (带滞后) │ │ (防抖)
│ └────────────────┘ │
└──────────────────────┘
快速开始
SCRIPTS=~/.claude/skills/embedded-debug/scripts
CFG="--config=$PWD/.target.conf"
# 启动后台 daemon(socat + 日志 + agent 服务器)
uv run $SCRIPTS/monitor.py $CFG start &
# 查看目标状态
uv run $SCRIPTS/monitor.py $CFG status
# 向目标发送命令
uv run $SCRIPTS/monitor.py $CFG send-cmd "uname -a"
# 硬件复位 + 日志切割
uv run $SCRIPTS/monitor.py $CFG reset
# 仅切割日志(不复位)
uv run $SCRIPTS/monitor.py $CFG new-log
# 强制进入 U-Boot 提示符
uv run $SCRIPTS/monitor.py $CFG enter-uboot
# 查看日志
uv run $SCRIPTS/monitor.py $CFG log-tail --lines 50
uv run $SCRIPTS/monitor.py $CFG log-tail --list
uv run $SCRIPTS/monitor.py $CFG log-tail --archive 0 --pattern panic
uv run $SCRIPTS/monitor.py $CFG log-tail --follow
# 等待模式匹配
uv run $SCRIPTS/monitor.py $CFG wait-pattern "login:" 120
CLI 参考
| 命令 | 说明 |
|---|---|
start |
启动后台 daemon |
stop |
停止 daemon |
status |
显示目标状态 |
send-cmd <命令> |
在目标上执行命令 |
reset |
硬件复位 + 切割日志 |
new-log |
仅切割日志(不复位) |
enter-uboot |
强制目标进入 U-Boot |
log-tail [--lines N] [--pattern RE] [--archive N] [--list] [--follow] |
查看日志 |
wait-pattern <正则> [超时秒] [--action send_ctrl_c] |
等待模式出现 |
probe |
存活检测 |
配置(.target.conf)
# 目标连接(必填)
RK_DEV_HOST_IP=192.168.1.189
RK_SERIAL_PORT=2000
# 登录凭据(可选 — 用于自动登录)
RK_LOGIN_USER=root
RK_LOGIN_PASS=mypassword
# 启动检测模式(以下为默认值)
# RK_BOOT_COMPLETE_PATTERN=login:
# RK_SHELL_PROMPT=[#\$] $
# 监控参数
RK_HANG_TIMEOUT=60 # 判定目标挂死的无输出超时秒数
RK_HANG_HYSTERESIS=3 # 状态切换需连续确认次数
RK_MAX_ARCHIVED_LOGS=50 # 保留最近 N 个启动日志
# 继电器控制(可选 — 用于硬件复位)
RK_DEV_HOST_USER=linaro
RK_RELAY_DEVICE=/dev/ttyUSB0
RK_RESET_PORT=2
RK_RELAY_BIN=serial_relay
多 Agent 使用
每个 Agent 通过 Unix socket 独立连接到 daemon:
from agent_client import AgentClient
client = AgentClient(config_path=".target.conf")
client.connect()
# 发送命令 — 响应仅路由回此客户端
output = client.send_command("cat /proc/device-tree/model", timeout=10)
print(output)
# 流式接收广播的串口输出
for line in client.stream():
print(line)
client.close()
Agent 之间互不干扰 — daemon 通过队列串行化命令,按唯一标记 ID 路由响应。
Hook 集成
~/.claude/hooks/embedded-debug/ 中的所有 hook 均为 Python 脚本,通过 uv run 执行。
| Hook | 脚本 | 触发时机 | 作用 |
|---|---|---|---|
| SessionStart | session-start.py |
进入项目 | 自动启动 daemon |
| Stop | session-stop.py |
退出会话 | no-op(daemon 跨会话持久化) |
| UserPromptSubmit | user-prompt-submit.py |
每次提示前 | 目标挂死/崩溃告警 |
| statusLine | statusline.py |
每 5 秒 | 状态指示器 |
状态栏指示器:● serial:active(绿色)、⚠ serial:DUT-off(红色)、◐ serial:disconnected(红色)。daemon 未运行时不显示。
文件结构
~/.claude/skills/embedded-debug/
├── README.md # 本文件 — 架构与使用说明
├── SKILL.md # Claude Code 的 Skill 定义
└── scripts/
├── config.py # 配置加载(所有模块共享)
├── patterns.py # 模式检测引擎
├── daemon.py # 核心 SerialDaemon(socat + 日志 + agent 服务器)
├── agent_client.py # 单 Agent Unix socket 客户端
├── monitor.py # CLI 入口
├── libmonitor.py # 向后兼容重导出
└── pyproject.toml # uv 项目配置
~/.claude/hooks/embedded-debug/
├── lib.py # 共享 hook 工具函数
├── session-start.py # 自动启动 daemon
├── session-stop.py # 退出会话(no-op)
├── user-prompt-submit.py # 目标告警
└── statusline.py # 状态栏指示器
日志管理
日志按 session 存储在 /tmp/embedded-debug/{session_id}/logs/:
boot-001_20260609_120000.log # 第一个启动周期
boot-002_20260609_143000.log # 复位/新启动后的日志
...
serial.current.log → boot-003_...log # 指向当前日志的符号链接
自动切割:当 daemon 检测到启动签名(U-Boot SPL、DDR Version 等),自动归档当前日志并创建新日志。
手动切割:monitor.py reset 或 monitor.py new-log 向 daemon 发送 SIGUSR1,触发立即切割。
保留策略:保留最近 N 个启动日志(通过 RK_MAX_ARCHIVED_LOGS 配置,默认 50)。
状态机
initializing → active → booting → booted
↘ ↘
uboot crashed
↘
DUT-off (无输出 > HANG_TIMEOUT)
↘
disconnected (socat TCP 连接断开)
↘
stopped (daemon 关闭)
状态切换使用滞后机制:条件必须连续满足 RK_HANG_HYSTERESIS 次才会变更状态,避免状态栏闪烁。
目标级排他锁
同一 host:port 只允许一个 daemon 运行。启动时 daemon 会检查:
- 同 session:如果当前项目的 session 下已有 daemon 存活,拒绝启动
- 跨 session:扫描
/tmp/embedded-debug/下所有 session,如果已有 daemon 连接同一 host:port,拒绝启动 - 残留清理:启动 socat 前,杀掉旧的 bash 版 monitor 残留进程(inotifywait、per-connect.sh)
错误处理
| 现象 | 原因 | 解决方法 |
|---|---|---|
| 状态栏不显示串口 | 无 .target.conf、daemon 未运行或 state 为 off |
monitor.py start 启动 daemon |
◌ serial:connecting |
socat 正在重建连接 | 等待数秒,daemon 会自动恢复 |
◐ serial:disconnected |
socat 无法连接 ser2net | 检查 .target.conf 中 IP/端口;确认网络可达 |
⚠ serial:DUT-off |
目标在启动中挂死或长时间无输出 | monitor.py send-cmd "echo ping" 探测;monitor.py reset 复位 |
⚠ serial:crashed |
内核 panic/BUG/Oops | monitor.py log-tail --archive 0 --pattern "panic|BUG|Oops" 查看崩溃日志 |
send-cmd 返回空 |
目标 shell 未就绪 | 等待 booted 状态;检查日志确认 login 提示已出现 |
| daemon 无法启动 | socat 缺失或串口冲突 | which socat;检查 daemon.log;确认没有其他 daemon 占用同一 host:port |
enter-uboot 无效 |
继电器通道错误或启动太快 | 手动测试继电器端口;尝试 RK_RESET_PORT=0 |
| 两个 daemon 争抢同一串口 | 两个项目目录指向同一 target | daemon 现在会自动检测并拒绝重复启动 |
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.