跳至内容

【工具】JLink MCP 使用教程:让 AI 直接调试单片机

本文以 PyPI 的 jlink-mcp 0.1.1 为例,介绍安装、MCP 客户端配置、J-Link 连接、内存与寄存器读取、断点、RTT、Flash 操作及常见故障排查。

J-Link 通常由 Keil、Ozone、J-Link Commander 或 GDB 直接控制。jlink-mcp 在这套链路前面增加了一个 MCP 服务器,让支持 Model Context Protocol 的 AI 客户端能够调用 J-Link:列出探针、连接目标芯片、暂停 CPU、读取内存和寄存器、设置断点、查看 RTT,甚至执行 Flash 操作。

本文以 PyPI 上的 jlink-mcp 0.1.1 为准。实测可以通过 uvx 启动服务器,完成 MCP 握手并发现 41 个工具。需要先说明的是,这个版本在 PyPI 中标记为 Alpha;本文验证了安装、启动和工具发现,没有在当前测试环境中连接真实 J-Link,因此涉及写内存和烧录的部分会采用偏保守的操作方式。

名称容易混淆:PyPI 包名和命令名是 jlink-mcp,Python 模块名是 jlink_mcp。直接搜索或安装 jlinkmcp 会找不到对应的 PyPI 项目。

文章目录

jlink-mcp 的工作方式

MCP 客户端(Claude、Cursor 等)
        │  stdio / MCP
        ▼
jlink-mcp Python 服务器
        │
        ▼
pylink-square → SEGGER J-Link 动态库
        │
        ▼
J-Link 探针 → SWD/JTAG → 目标 MCU

AI 客户端不会直接访问 USB 或芯片。它先选择一个 MCP 工具并填写参数,jlink-mcp 再通过 pylink-square 调用本机安装的 SEGGER J-Link 软件。服务器使用本地 stdio 通信,因此 J-Link 驱动、固件文件和目标板都应位于运行 MCP 服务器的那台电脑上。

它更像“J-Link 的 MCP 适配层”,而不是一个以 import jlinkmcp 为主要用法的普通 Python SDK。日常使用时,通常只需配置一次 MCP 服务器,之后用自然语言描述调试任务。

准备硬件和软件

项目 要求
Python 以包元数据为准,需要 Python 3.10 或更高版本
J-Link 软件 安装 SEGGER J-Link Software and Documentation Pack
调试器 J-Link BASE、PLUS、EDU、OB 等受 SEGGER 支持的探针
目标板 正确供电,并连接 SWD 或 JTAG 信号及 GND
MCP 客户端 支持本地 stdio MCP 服务器的客户端

先用 SEGGER 自带的 J-Link Commander 检查驱动和探针。如果官方工具都无法识别 J-Link,MCP 服务器也不会成功。Linux 用户还应安装 SEGGER 提供的 udev 规则,并确认当前用户有权访问 USB 设备。

另一个常见冲突是探针被其他软件占用。启动 jlink-mcp 前,应结束 Keil 调试会话、Ozone、J-Link Commander 和独立的 J-Link GDB Server。同一支探针通常不能同时交给两个调试程序控制。

安装 jlink-mcp

方式一:使用 uvx,适合 MCP 配置

uvx 会为工具创建隔离环境,不会污染系统 Python。安装 uv 后先在终端执行:

uvx --from jlink-mcp==0.1.1 jlink-mcp

这是 stdio 服务器,启动后等待客户端发送 MCP 消息,不会出现图形界面。终端一直占用并不代表程序卡死,按 Ctrl+C 可以结束测试。

方式二:安装到虚拟环境

python -m venv .venv

# Linux / macOS
source .venv/bin/activate

# Windows PowerShell
# .venv\Scripts\Activate.ps1

python -m pip install --upgrade pip
python -m pip install jlink-mcp==0.1.1
jlink-mcp

也可以使用模块入口启动:

python -m jlink_mcp

确认实际安装版本

建议从 Python 包元数据读取版本,而不是依赖模块内的 __version__

python -c "from importlib.metadata import version; print(version('jlink-mcp'))"

正确安装 0.1.1 时会输出 0.1.1

接入 MCP 客户端

在客户端的 MCP Server 配置中加入以下内容。不同客户端保存配置的入口不同,但服务器定义基本一致:

{
  "mcpServers": {
    "jlink": {
      "command": "uvx",
      "args": [
        "--from",
        "jlink-mcp==0.1.1",
        "jlink-mcp"
      ]
    }
  }
}

如果客户端提示找不到 uvx,先在终端运行 which uvx(Linux/macOS)或 where uvx(Windows),然后把 command 改成返回的绝对路径。

使用虚拟环境时,则直接指定该环境中的 Python:

{
  "mcpServers": {
    "jlink": {
      "command": "/absolute/path/to/.venv/bin/python",
      "args": ["-m", "jlink_mcp"]
    }
  }
}

Windows 路径示例为 C:\\tools\\jlink-mcp\\.venv\\Scripts\\python.exe。JSON 中的反斜杠需要写成双反斜杠。

可选的 SVD 和设备补丁目录

只有在需要 SVD 寄存器解析或厂商设备补丁时才配置这些变量:

{
  "mcpServers": {
    "jlink": {
      "command": "uvx",
      "args": ["--from", "jlink-mcp==0.1.1", "jlink-mcp"],
      "env": {
        "JLINK_SVD_DIR": "/absolute/path/to/svd",
        "JLINK_PATCH_DIR": "/absolute/path/to/patches"
      }
    }
  }
}

jlink-mcp 0.1.1 的连接工具默认接口是 JTAG。很多 STM32、nRF52 开发板实际使用 SWD,所以不要依赖默认值;在连接指令中明确写出 interface="SWD"interface="JTAG"

保存配置后彻底退出并重启 MCP 客户端。客户端若能显示 list_jlink_devicesconnect_device 等工具,说明服务器已接入。

第一次连接目标板

首次使用先做只读检查,不要一上来就烧录。可以把下面这段直接发给 AI 客户端:

先只做只读检查,不要写内存、不要复位、不要擦除 Flash:
1. 调用 list_jlink_devices 列出 J-Link;
2. 使用 SWD 连接 STM32F407VG;
3. 查询连接状态、目标信息和目标电压;
4. 把每一步的返回结果原样摘要给我。

正常情况下,客户端会按顺序使用:

list_jlink_devices()
connect_device(chip_name="STM32F407VG", interface="SWD")
get_connection_status()
get_target_info()
get_target_voltage()

电脑上连接了多支 J-Link 时,应把序列号写进指令,避免控制错设备:

只连接序列号为 123456789 的 J-Link,
目标芯片 STM32F407VG,接口 SWD。
连接后只读取状态和电压,不执行任何写操作。

常用调试流程

读取 CPU 寄存器和一段 RAM

读取前明确暂停 CPU,完成后再恢复运行。这样可以避免读到变化中的数据,也能减少 J-Link 返回 target running 一类错误。

确认已经连接目标板后:
1. 暂停 CPU;
2. 读取 PC、SP、LR 和 R0-R3;
3. 从 0x20000000 读取 64 字节,访问宽度 32 位;
4. 用十六进制显示结果;
5. 不修改任何数据,最后恢复 CPU 运行。

对应工具大致是:

halt_cpu()
read_registers(register_names=["PC", "SP", "LR", "R0", "R1", "R2", "R3"])
read_memory(address=0x20000000, size=64, width=32)
run_cpu()

read_memory 单次最多读取 64KB,实际调试时建议只取需要的范围。地址还要满足访问宽度的对齐要求。

设置断点并单步

目标已通过 SWD 连接。请按以下顺序执行:
1. 复位并暂停;
2. 在 0x08001234 设置断点;
3. 运行到断点;
4. 查询 CPU 状态并读取 PC、SP、LR;
5. 单步执行一条指令,再读取 PC;
6. 清除 0x08001234 的断点;
7. 恢复运行。
任何一步失败都停止,不要继续执行后续写操作。

当前发布版按地址设置断点,不负责从 ELF 文件解析函数名。如果想在 main 上断下,需要先从 MAP/ELF 工具中获得地址,再交给 set_breakpoint

读取 RTT 日志

启动 RTT 通道 0,每次最多读取 1024 字节。
连续读取 10 秒,只整理以 ERROR 或 WARN 开头的行。
完成后调用 rtt_stop。

目标固件必须已经集成 SEGGER RTT,并保留可被 J-Link 找到的 RTT Control Block;否则服务器启动 RTT 后也读不到内容。

Flash 操作

这一部分要格外谨慎。0.1.1 暴露的 program_flash(address, data, verify) 接收的是字节数据,不是本地固件文件路径。把一个较大的 .hex.bin.elf 完整塞进 MCP 对话并不合适。完整固件烧录优先使用经过验证的 SEGGER 工具或项目原有下载流程。

如果只写入一小段、明确可恢复的数据,至少先让 AI 报告目标、地址、长度和操作类型,获得确认后再调用。建议使用如下约束:

先不要执行烧录。请先报告:
- 当前 J-Link 序列号和目标芯片;
- 擦除起止地址;
- 待写入数据长度;
- 是否启用写后校验。
禁止整片擦除。只有上述信息全部匹配后,才允许执行范围擦除和 program_flash(verify=true)。

启动 GDB Server

start_gdb_server 的默认监听地址是 0.0.0.0,可能把调试端口暴露给同一网络中的其他设备。只在本机使用时应显式绑定环回地址:

start_gdb_server(
    host="127.0.0.1",
    port=2331,
    device="STM32F407VG",
    interface="SWD",
    speed=4000
)

41 个 MCP 工具速查

类别 数量 主要工具
连接管理 5 list_jlink_devicesconnect_devicedisconnect_deviceget_connection_statusmatch_chip_name
目标信息 4 get_target_infoget_target_voltagescan_target_deviceslist_device_patches
内存与 CPU 寄存器 4 read_memorywrite_memoryread_registerswrite_register
Flash 3 erase_flashprogram_flashverify_flash
调试控制 7 reset_targethalt_cpurun_cpustep_instruction、断点工具等
RTT 5 rtt_startrtt_readrtt_writertt_stoprtt_get_status
GDB Server 3 start_gdb_serverstop_gdb_serverget_gdb_server_status
SVD 5 列出 SVD、查询外设/寄存器、读取并解析字段
使用指导 5 get_usage_guidanceget_best_practiceslist_scenarios

连接、读写和调试工具共 36 个,另有 5 个使用指导工具,总计 41 个。客户端实际显示的工具清单才是所安装版本的准确信息;GitHub 主分支可能比 PyPI 发布版更新。

常见问题

提示 “Expected to be given a valid DLL”

这表示 pylink-square 没有找到可用的 SEGGER J-Link 动态库。安装或修复 J-Link Software and Documentation Pack,然后彻底重启 MCP 客户端。还可以先运行 J-Link Commander,确认官方程序能够枚举探针。

能启动服务器,但列不出 J-Link

  • 更换 USB 线和 USB 端口,排除仅供电线;
  • 关闭 Keil、Ozone、Commander 和其他 GDB Server;
  • 确认 Linux udev 规则已经安装;
  • 检查容器或远程环境是否真的映射了 USB 设备。

连接芯片失败

  • 显式指定 SWD 或 JTAG,不依赖默认 JTAG;
  • 确认目标板供电和 VTref 电压正常;
  • 使用 SEGGER 设备数据库中的芯片名称;
  • 多探针环境中指定 J-Link 序列号;
  • 先在 J-Link Commander 中用同一芯片名测试。

读取内存或寄存器失败

先调用 halt_cpu。然后检查地址是否合法、访问宽度是否为 8/16/32 位、地址是否正确对齐。读取完成后如需继续运行,再调用 run_cpu

启动时提示 SVD 或 Flagchip 补丁文件不存在

PyPI 0.1.1 在部分环境中会打印可选资源目录不存在的警告。基础的连接、CPU 控制和普通内存访问不一定因此失效;需要 SVD 字段解析或特定芯片补丁时,再通过 JLINK_SVD_DIRJLINK_PATCH_DIR 指向外部资源目录。

运行 jlink-mcp 后一直没有返回

这是正常现象。它是等待 MCP 客户端输入的 stdio 服务,不是一次性命令。日常使用应由 MCP 客户端负责启动和关闭它。

README 写 Python 3.8+,安装器却拒绝

以 PyPI 包元数据为准:jlink-mcp 0.1.1 要求 Python 3.10 或更高版本。README 徽章与包元数据存在差异时,pip/uv 会执行后者。

安全使用建议

  • 先读后写:第一次连接只枚举设备、读取状态和电压。
  • 每次确认身份:写操作前核对 J-Link 序列号、芯片型号和接口。
  • 显式限定范围:给出地址和长度,避免“帮我清一下 Flash”这类模糊指令。
  • 暂停后访问:读写内存和寄存器前先暂停 CPU,结束后按需恢复。
  • 默认禁止整片擦除:只有明确需要并且已有可恢复固件时才设置 chip_erase=true
  • 保留人工确认:量产板、带校准数据的设备和熔丝/安全区操作不要完全交给自动流程。
  • 限制网络暴露:GDB Server 只供本机使用时绑定 127.0.0.1

快速检查清单

  1. 安装 SEGGER J-Link 软件,并用 Commander 识别探针;
  2. 准备 Python 3.10+ 与 uv;
  3. 在 MCP 配置中使用 uvx --from jlink-mcp==0.1.1 jlink-mcp
  4. 重启客户端,确认能看到 41 个工具;
  5. 第一次连接明确写出芯片名、序列号和 SWD/JTAG;
  6. 先执行只读检查,再进行调试或写入;
  7. Flash 操作前再次确认地址、长度、擦除范围和校验选项。

jlink-mcp 最适合把“重复但需要判断”的调试步骤交给 AI,例如采集寄存器、读取一小段 RAM、整理 RTT 错误日志。对于整片擦除、大固件下载和不可逆安全配置,成熟的下载脚本与人工复核仍然更可靠。

参考资料

发送评论