Mdkdebug
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| MDKDEBUG_DESC | No | Description verbosity for MCP tool descriptions. Allowed values: 'full' (default), 'lean', or 'min'. 'lean' keeps ~360 characters, 'min' keeps only a one-sentence summary. | full |
| MDKDEBUG_COMPACT | No | Global default for the `compact` output-control flag. Set to '1' to enable compact mode by default for high-output tools. | 0 |
| MDKDEBUG_TOOLSETS | No | Comma-separated list of toolset groups to load at startup, e.g. 'serial', 'core,build', 'toolchain,target,ocd,trace', 'all', or 'nano'. Overrides the default tool surface. | |
| MDKDEBUG_MAX_LINES | No | Global default for the `max_lines` output-control parameter. Limits the number of entries in list-type results, e.g. '200'. | |
| MDKDEBUG_STATE_FILE | No | Path to the cross-session state file. Default is ~/.mdkdebug/state.json. Can also be set via the `path` parameter of `session_state`. | ~/.mdkdebug/state.json |
| MDKDEBUG_SYMBOL_PROJECTS | No | JSON array of custom symbol projects to inject, each with name, axf, map, flash_start, flash_size (decimal integers). Example: [{"name":"myproj","axf":"D:/board/out.axf","map":"D:/board/out.map","flash_start":134217728,"flash_size":1048576}] | |
| MDKDEBUG_NO_LAUNCH_DISCOVERY | No | Set to '1' to disable automatic .vscode/launch.json discovery when no connection parameters are given to `ocd_start`. | 0 |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| get_versionA | 查询 Keil UVSOCK 插件的版本信息,返回十六进制版本串。注意:需 Keil 已启动且已开启 UVSOCK(Edit→Configuration→Other→UVSOCK Enabled→端口4823→重启Keil),否则连接失败并返回开启指引。 【参数】无(直接调用) 【调用示例】{} |
| get_statusA | 查询当前调试状态:是否处于调试会话、目标是否在运行、以及 UVSOCK 状态码,并额外返回 symbol_file / symbol_mtime / symbol_stale(当前符号文件路径、时间戳,以及「符号是否已与本次调试会话不一致」——编译或烧录之后旧会话的符号即过期,继续求值会报 status 13 解析错误)与 serialization(串行化方式、并发竞争遥测、是否还有别的 mdkdebug 进程在抢同一 UVSOCK)。可用于判断可否安全读写内存。注意:UVSOCK 响应的 r_status 恒为 0,真实运行状态在 data 低字节(0=停止,1=执行中),本工具已正确解析。目标运行中可查状态,但此时不可安全读内存。 【参数】无(直接调用) 【调用示例】{} |
| read_console_outputA | 读取 Keil 命令窗口(Command)的调试输出,来自 UVSOCK 推送的 UV_DBG_CMD_OUTPUT(0x5020) 异步消息。执行 EXEC_CMD / BL / EVAL / 断点 等命令后,其输出(如断点列表、EVAL 结果、printf 调试打印、错误行)通过本工具读取,实现调试信息闭环。clear 可选清空缓存。注意:输出为异步推送,需先执行命令再读;每次发送请求前会自动收集堆积的异步帧。 【参数】必填: 无;可选: clear 【调用示例】{} 【参数别名】clear ← drain/flush/reset。规范名以上方【参数】行为准;未列出的参数名会被拒绝,不会静默忽略 |
| read_async_messagesA | 读取 Keil 异步消息与报错信息,来自 UVSOCK 推送的 UV_ASYNC_MSG(0x4000)。包含命令执行状态(status)与报错文本(如 '*** error 34: undefined identifier'、编译/烧录/调试失败的弹窗报错内容),用于闭环捕获 Keil 侧错误。clear 可选清空缓存。注意:报错为异步推送,先执行可能出错的操作再读;status 为 Keil 返回的错误码。 【参数】必填: 无;可选: clear 【调用示例】{} 【参数别名】clear ← drain/flush/reset。规范名以上方【参数】行为准;未列出的参数名会被拒绝,不会静默忽略 |
| keil_commandA | 把一条命令原样送进 Keil 命令窗口执行(走 UVSOCK 的 EXEC_CMD),并把命令窗口输出/报错一并带回来。本工具是「万能兜底」:当某个专用工具不覆盖你要的操作时,用官方命令直接做,不必等封装。
常用命令:
|
| calc_expressionA | 计算并读取调试器中的一个表达式(变量名、寄存器、指针解引用等)。例如传入全局变量名 'SData_UA'、'timer.sec',或 '(uint32_t)0x20000000'。返回表达式在当前断点处的值及其类型。注意:需已进入调试且目标暂停,目标运行中无法求值。刚 run 到断点停止的瞬间读取表达式可能返回脏值(如 PC=1),必要时重试。 【参数】必填: expr;可选: 无 【调用示例】{"expr": "main"} 【参数别名】expr ← expression/func/function/keyword/location/name/pattern/query/symbol/target/var/variable。规范名以上方【参数】行为准;未列出的参数名会被拒绝,不会静默忽略 |
| read_variableA | 按变量名查询变量的内存地址与当前内容(值),支持数组等类型。内部用 '&变量名' 取地址、'变量名' 取值、'sizeof(变量名)' 取大小,AI 无需手写取地址表达式即可定位变量。name 为变量名(如 'SData_UA'、'timer.sec'、'arr');count 可选:>0 时按数组逐元素读 name[0..count-1] 返回 elements;返回 {address, value, value_type, size_bytes, elements, memory_hex}。读 App 侧变量(运行期重定位过)时传 reloc_delta="0xF000",或先调 set_reloc_delta 设一次全局偏移:工具会把符号的链接地址 + 偏移当作运行地址去读,返回 link_address / run_address,不必再手工换算(此时 value 按小端整数解析内存,浮点看 value_as_float)。符号解析双轨(批次48):Keil 表达式这条路读不到时(static 变量、符号漂移、停在不相关位置),会自动改走 .axf 符号表地址 + read_mem 兜底,返回 fallback=".axf 符号表 + read_mem" 与 fallback_reason 说明为什么换了轨道;两条都不通就如实报错,不会给一个像样的假值。若返回 value_suspect/value_warning(读回整帧全 0x00/全 0xFF),不要据此判定「变量被清零」——先用 reloc_check 校验 reloc_delta 是否与实际布局相符。适合先查地址/数组内容,再配合 read_mem/write_mem 进一步读写。注意:需目标暂停(运行中读取会失败/错位);依赖 .axf 调试符号。刚停止瞬间取值可能读到脏值。 【参数】必填: name;可选: count, read_memory, reloc_delta 【调用示例】{"name": "SData_UA"} 【参数别名】name ← arr/expression/func/function/keyword/location/pattern/query/symbol/target/var/variable/varname;count ← items/length/n/num。规范名以上方【参数】行为准;未列出的参数名会被拒绝,不会静默忽略 |
| read_memA | 从指定内存地址读取 n_bytes(别名 length,二者传其一)个字节。addr 支持十六进制(如 '0x20000000')、十进制,或符号名(如 'SystemCoreClock'、'svcrt_task_table'——自动查当前 .axf 符号表解析,命中时返回 addr_note 说明来源);读 App 侧符号可传 reloc_delta="0xF000"(或先用 set_reloc_delta 设全局),工具会把符号的链接地址偏到运行地址;显式数字地址不会被偏移;返回十六进制字节串及 ASCII 视图。脏读防护(verify,默认 "auto"):stop 之后紧跟的第一次读可能整帧返回全 0(真机实测 0x08022000 读出 16 个 00,重读即正确)——auto 会在「首帧整帧退化(全 0x00/全 0xFF)或距最近一次 stop 不足 1 秒」时自动复读,连续两次一致才采纳,并返回 read_confidence(high/low)、reread_count、reread_consistent、degenerate、since_stop_s;首帧是脏值时用 first_read_hex 留证、data_hex 换成可靠值并给 warning。verify=true 总是复读(强制确认),verify=false 关闭(大块搬运省时间);verify 可传字符串也可传 JSON 布尔(true/false 等价于 "true"/"false")。运行态读取(running,默认 "live"):目标全速运行时也能读(真机实测 SRAM 与外设寄存器都读得到,不必先 stop);运行态一律多复读一轮,两次不一致时给read_confidence=medium + read_unstable=true + while_running,并把「该地址本来就在被 CPU改写」与「这次读被运行中的目标打断了」两种可能都写明(不替你选一个)。要取某一瞬间的一致快照,用 running="halt"(停-读-走):会暂停目标再恢复,返回paused_ms / was_running / resumed / halt_note 如实交代代价,恢复失败会告警。**看到 read_confidence="low"/"medium" 或 degenerate 时不要据此下结论(例如「读到 0 就判定变量被清零」)。**勿越界读外设保留区,可先 query_memory_map 确认范围。 【输出控制】本工具返回体可能较大,额外接受三个可选参数:compact=true(精简)/ max_lines=N(限制列表条数)/ full=true(强制全量)。默认都不传=行为不变;被裁掉的内容一定会在返回体的 output 字段里如实上报(truncated/dropped/trimmed/hint),不会静默丢数据。也可用环境变量 MDKDEBUG_COMPACT=1 / MDKDEBUG_MAX_LINES=N 设全局默认。 【参数】必填: addr, n_bytes;可选: length, reloc_delta, verify, running, compact, max_lines, full(别名:n_bytes 也可写作 length) 【调用示例】{"addr": "0x20000000", "n_bytes": 16} 【参数别名】addr ← address/expression/location/name/pc/symbol/target;n_bytes ← bytes/count/nbytes/size。规范名以上方【参数】行为准;未列出的参数名会被拒绝,不会静默忽略 |
| write_memA | 向指定内存地址写入字节。data_hex 为十六进制字节串(偶数长度),如 'de ad be ef' 或 'deadbeef'(自动去空格)。返回实际写入长度,并默认做写后回读校验(verify=true,返回 verified/readback_hex):并发写入、目标运行中、或写只读/未擦写区域时,写入可能被静默忽略——verified=false 即明确告诉你「写下去了但没生效」,不要据此推断目标行为(如误判为看门狗复位)。addr 支持十六进制/十进制/符号名。运行态写入(running,默认 "live"):目标全速运行时也能写(回读校验会告诉你有没有落地),但写入可能被 CPU 后续改写或缓存回行覆盖;要确保写进去就生效,用 running="halt"(停-写-回读-走,返回 paused_ms / was_running / resumed / halt_note)。写外设寄存器/关键内存有副作用,写入前确认地址与值正确(可先 read_mem 备份)。 【参数】必填: addr, data_hex;可选: verify, running 【调用示例】{"addr": "0x20000000", "data_hex": "deadbeef"} 【风险】高——不可逆:会改写目标 Flash/内存,或关闭/重启用户的 Keil 实例。执行前确认目标与工程正确。 【参数别名】addr ← address/expression/location/name/pc/symbol/target;data_hex ← bytes/data/hex/value。规范名以上方【参数】行为准;未列出的参数名会被拒绝,不会静默忽略 |
| enter_debugA | 自动进入 Keil 调试模式(UV_DBG_ENTER)。若目标本来就在调试态(status=10 正在调试),不会报失败,而是返回 ok=true + already_in_debug=true + note,可省掉一轮 exit/enter;返回 ready/ready_waited_ms 表示已确认就绪。受工程 Load/Flash Download/Run-to-main 设置影响,属于有副作用的操作:若工程 Utilities 勾选了 Update Target before Debugging(.uvprojx 的 Utilities/Flash1/UpdateFlashBeforeDebugging=1),Keil 会在进入调试前自动把最新 .axf 下载进 Flash(等价一次烧录)——此时编译完直接 enter_debug 即可,不必先 flash_download;该选项为 0 时 Keil 不下载,板上可能仍是旧固件(可用 read_project_config 查该字段)。进入后即可设断点、读变量、运行控制。注意:若当前 Keil 是旧窗口、加载旧固件,进入后调试的是旧代码符号;建议改用 flash_debug 闭环(关旧Keil→编烧→重开→进调试)。受工程 Load/Flash Download/Run-to-main 设置影响,属有副作用操作。需 UVSOCK 已开启。真机实测:进入调试是异步的——命令返回成功时目标尚未挂载完成,约 0.6~0.7s 后才真正就绪,期间紧接的读内存/表达式/断点命令会返回 status=6(Target is not in debug mode)。本工具已自动轮询等待就绪(默认最多 6s),返回 ready 与 ready_waited_ms;若超时未就绪会给出 warning,此时先读内存会失败,请检查目标板连接或 Keil 是否弹窗待确认。看门狗防御(真机踩过):新会话/复位后 DBGMCU 的 IWDG/WWDG 冻结位会被清零,目标 halt 超过看门狗溢出时间(典型 |
| exit_debugA | 自动退出 Keil 调试模式(UV_DBG_EXIT)。注意:目标处于运行状态时退出会被拒(status=11),需先 stop 再 exit_debug。退出成功后会顺带释放宿主机串口监听占用的 COM 口(否则调试完了串口还占着,Keil 串口窗口/其他工具打不开,WinError=5);释放只放端口,已收日志仍保留、serial_read 继续可读,需要接着采集重新 serial_monitor_start() 即可。 【参数】无(直接调用) 【调用示例】{} 【风险】中——会改变目标状态或占用共享资源(调试态/串口/Keil 实例),必要时可回退。 |
| set_breakpointA | 在指定符号或地址处设置软件断点。expr 可为函数名/变量名(如 'main')或地址(如 '0x08001034')。返回是否成功。地址路径与符号路径做同一套归一:入参地址若带 Thumb 位(bit0=1,常见于函数指针)会自动按偶地址下断并返回 thumb_bit_stripped/address_normalized——真机实测 Keil 的 BS 对奇数地址一律报 |
| clear_breakpointA | 清除断点。三种指定方式(任选其一):expr 传符号/地址;bp_id 传本服务内部 id;keil_number 传 Keil 界面/命令窗口 BL 里的真实断点编号。清除走命令窗口 BK:数据观察点按地址清不掉(BK <地址> 时 UVSOCK 回成功、窗口却报 error 72 invalid item number),必须按编号清除,故内部会自动把地址/符号解析成 Keil 编号再 BK <编号>,解析不出才回退按地址。bp_id 在本服务内无此 id 时会自动改按 Keil 真实编号处理并给出 note,不必再用 clear_all_*(hard=true) 一刀切。注意:清除断点同样走命令窗口并触发异步消息,清除后立即 run/step 前建议稍等。需已进入调试。 【参数】必填: 无;可选: expr, bp_id, keil_number 【调用示例】{} 【风险】中——会改变目标状态或占用共享资源(调试态/串口/Keil 实例),必要时可回退。 【参数别名】expr ← addr/address/expression/func/function/keyword/location/name/pattern/pc/query/symbol/target/var/variable;bp_id ← bp/breakpoint_id/id;keil_number ← keil_id/keil_no/num/number。规范名以上方【参数】行为准;未列出的参数名会被拒绝,不会静默忽略 |
| list_breakpointsA | 列出断点。返回两部分:① 本服务内部记录(breakpoints/内部 id,用于按 bp_id 清除);② real 字段——本会话 Keil 的真实断点表(解析命令窗口 BL 输出获得,含 Keil 断点编号、类型 exec/access、地址、CNT、enabled)。注意:真机实测本版 Keil 的 CNT 是断点的计数条件设置值(.uvoptx 的 break_if_rcount),不随命中递增,不能当命中次数用。real 才是板上实际生效的断点:.uvoptx 持久化断点、数据观察点都会出现在这里。注意清除数据观察点必须按 Keil 编号(按地址会报 error 72)。另附 uvoptx 字段暴露工程里 BK 清不掉、下次进调试会自动恢复的持久化断点。③ hardware 字段:直接读 Cortex-M 的硬件断点单元 FPB(FP_CTRL@0xE0002000 / FP_COMP0@0xE0002008),给出 check(clean/residue/unavailable)、启用的比较器与地址。real 是 Keil 的逻辑表、hardware 是硬件里实际写着的项——两者是两回事:BK * 之后 real 可能为空、FPB 里却还留着,J-Link 会一直报 "two breakpoints at the same address"。hardware.orphans 给出「硬件里有、real 里查不到」的地址(这类就是清不掉的残留);读不到 FPB 时为 unavailable,不当作「干净」(没测 ≠ 没有)。 【输出控制】本工具返回体可能较大,额外接受三个可选参数:compact=true(精简)/ max_lines=N(限制列表条数)/ full=true(强制全量)。默认都不传=行为不变;被裁掉的内容一定会在返回体的 output 字段里如实上报(truncated/dropped/trimmed/hint),不会静默丢数据。也可用环境变量 MDKDEBUG_COMPACT=1 / MDKDEBUG_MAX_LINES=N 设全局默认。 【参数】必填: 无;可选: compact, max_lines, full 【调用示例】{} |
| clear_all_breakpointsA | 清除软件断点:清空本服务内部记录并逐个按确切地址发 BK。include_uvoptx=True 时一并清除工程 .uvoptx 中 Keil 持久化的断点(BK 清不掉、下次进调试会自动恢复的残留)。注意:Cortex-M 目标经 SWD/JTAG 调试时,未超出硬件断点槽位(FPB)的代码断点走硬件断点,清除不涉及改写 Flash,无需重新烧录;仅当断点数量超出硬件槽位而落到 Flash 软件断点、或使用模拟器(Simulator)时才需重新烧录恢复原指令。清理 .uvoptx 需 Keil 已关闭(否则被内存断点回写覆盖)。hard=True 走 BK * 之后会复核硬件断点单元(FPB)(fpb 字段):Keil 的逻辑表干净了、硬件里还留着启用项时,本工具不会报 ok——那正是 J-Link 一直报 "two breakpoints at the same address" 的成因(error_code=breakpoint-residue,含 enabled_addrs 与 next_actions)。FPB 读不到时如实标 unavailable,不当成清干净。 【参数】必填: 无;可选: include_uvoptx, hard 【调用示例】{} 【风险】高——不可逆:会改写目标 Flash/内存,或关闭/重启用户的 Keil 实例。执行前确认目标与工程正确。 【参数别名】include_uvoptx ← uvoptx/with_uvoptx;hard ← force/hard_clear。规范名以上方【参数】行为准;未列出的参数名会被拒绝,不会静默忽略 |
| set_symbol_fileA | 运行时切换调试符号文件,解决符号绑定错误(find_symbol/get_current_location/断点行号解析到错误的 .axf)问题。path 支持 .axf(完整 DWARF 行号/局部变量)或 .map(函数/全局符号地址,无行号)。加载成功返回符号条目数;失败给出明确错误(文件不存在/无DWARF/格式不支持)。注意:建议 AI 落地后先 list_symbol_projects 查看候选,再 set_symbol_file 切到当前正在调试的固件符号,避免符号漂移误判。 【参数】必填: path;可选: 无 【调用示例】{"path": "path/to/firmware.axf"} 【风险】中——会改变目标状态或占用共享资源(调试态/串口/Keil 实例),必要时可回退。 【参数别名】path ← axf/axf_path/file/symbol_file。规范名以上方【参数】行为准;未列出的参数名会被拒绝,不会静默忽略 |
| list_symbol_projectsA | 返回预登记的可切换符号工程(如 SVCRTOS_TEST 内核、mdk_test),含 .axf/.map 路径与 flash 地址段。AI 据此了解可切换的符号目标,并可与 set_symbol_file 配合把符号切到当前调试固件。flash 段用于 PC 自动匹配(辅助)。注意:仅列出本机存在的候选。 【输出控制】本工具返回体可能较大,额外接受三个可选参数:compact=true(精简)/ max_lines=N(限制列表条数)/ full=true(强制全量)。默认都不传=行为不变;被裁掉的内容一定会在返回体的 output 字段里如实上报(truncated/dropped/trimmed/hint),不会静默丢数据。也可用环境变量 MDKDEBUG_COMPACT=1 / MDKDEBUG_MAX_LINES=N 设全局默认。 【参数】必填: 无;可选: compact, max_lines, full 【调用示例】{} |
| diagnoseA | 聚合一次排查所需的所有现场信息:CPU 寄存器组(含 AAPCS 解读) + PC 处指令反汇编 + 源码上下文 + 完整调用栈 + 当前函数局部变量 + 指定关键全局变量,生成结构化现场报告。AI 接到 bug 报告后一次调用即可看清程序卡在哪、寄存器状态、正在执行什么指令、谁调进来的,避免多次 get_current_location/read_registers/disassemble/read_locals 往返。globals 可选,传关键全局变量名列表(数组或逗号/分号分隔字符串均可)。需已进入调试且配置 .axf。注意:聚合多个只读诊断,同样受中断上下文限制——停在 SysTick 中断/全速运行后手动 stop 时,局部变量与完整调用栈可能受限/为空。需已进入调试且配置 .axf。 【输出控制】本工具返回体可能较大,额外接受三个可选参数:compact=true(精简)/ max_lines=N(限制列表条数)/ full=true(强制全量)。默认都不传=行为不变;被裁掉的内容一定会在返回体的 output 字段里如实上报(truncated/dropped/trimmed/hint),不会静默丢数据。也可用环境变量 MDKDEBUG_COMPACT=1 / MDKDEBUG_MAX_LINES=N 设全局默认。 【参数】必填: 无;可选: globals, source_context, disasm_count, compact, max_lines, full 【调用示例】{} 【参数别名】globals ← expressions/exprs/names/variables/vars/watches;disasm_count ← code_lines/count/disasm。规范名以上方【参数】行为准;未列出的参数名会被拒绝,不会静默忽略 |
| env_checkA | 一键核对「工程与工具以为的目标」和「板上真实的目标」是否一致——跨仓库/跨板调试最毒的两类问题都在这里设防:①符号与板上固件不同源(PC 被解析成假符号);②SVD/内置寄存器表选错芯片(读出别的芯片布局下「看着像样」的值)。 输出包含:chip(实测 DBGMCU_IDCODE + CPUID 推出的型号/系列/置信度)、configured(工程 / 内置寄存器表 / 已加载 SVD 各自的系列,以及逐项 matched/mismatched/unknown 判定)、firmware_symbol(符号与板上固件的内容指纹比对)、dcache(D-Cache 是否使能)、last_flashed(本进程最近一次烧录的工程与 .axf)、problems / next_actions。 判据一律拿目标说话:读不到 IDCODE 就说 unknown,不拿工程配置冒充实测结果;allow_mismatch 只影响「后续外设工具要不要放行」,不改变这里的判定。 guard 字段告诉你器件守卫这次到底有没有生效:active=false 表示没能实测出芯片型号(多数是目标没在调试态),此时外设级读数没有型号核对保护,请自行核对型号——别把「体检没报错」当成「一定没问题」。 链路是懒连接的:只连 UVSOCK 不会进调试/停机/下载,可以放心先跑本工具看环境。 【参数】必填: 无;可选: project, link, content_check 【调用示例】{} |
| runA | 让目标 MCU 全速运行(启动执行)。注意:run 后目标全速运行,此时读内存/寄存器/表达式会失败或错位(异步消息堆积),需先 stop 再读。目标运行期间 UVSOCK 会推送异步消息。若期望'运行到某断点停住',请以 get_current_location 实测 PC 停靠位置为准,run 本身返回的停靠信息不可信(PC 可能为脏值)。关于'看不到现象':调试是 halt 式的——只要 MCP/Keil 保持调试连接,目标要么被挂起、要么在被断点拦停,外设现象(LED、串口输出、周期动作)会随之停滞,这是调试的本质而非工具缺陷。要看真实运行现象,请在 run 之后不要再 stop/读内存/读寄存器,让目标自由运行;需要恢复观察时先 exit_debug(退出调试后目标按复位/运行设置自由执行)。 【参数】无(直接调用) 【调用示例】{} 【风险】中——会改变目标状态或占用共享资源(调试态/串口/Keil 实例),必要时可回退。 |
| wait_breakpointA | 带超时地等待目标停在断点上:轮询目标状态,一旦停止就读取 PC(含收敛判定与「是否真的停住」复查),回落到源码位置,返回 hit / hit_address / hit_count / waited_ms。用来确证「App 是否真的调用到内核某函数」,不必再靠读 PC 猜、也不必手工循环 get_status。symbol 传符号名(如 svcrt_ptable_lookup,自动解析为地址);address 传 0x 地址;两者都不传时用工程 .uvoptx 里的持久化断点作候选(use_project_breakpoints 控制)。命中后返回里直接带 file/line/callstack,并累计该地址命中次数(breakpoint_stats 可查全部)。只认「本次等待期间新发生的停止」:若调用时目标已停着(典型——刚被 run_timeout 停在某行再调本工具),那次停止不计为命中,会返回 hit=false、stop_is_new=false、ran_during_wait=false 且 note 说明「目标在等待期间未曾运行」,避免把「进来时已停」误报成「等到了断点命中」。故正确用法是先 run(或 reset 后 run)再调本工具;调用时先给一个很短的宽限窗口确认目标是真想跑(run 是异步命令,响应会滞后),若窗口内没见运行且 PC 相对调用时没有移动,才判为旧停止。注意:命中判定为「目标已停止 且 PC 等于候选地址」(自动兼容 Thumb 位),并额外支持数据观察点命中——数据断点触发时 PC 不等于观察地址,判定链路按证据强度递减:① 等待前后各读一次 Keil 断点表的 CNT,某条 CNT 增加即为命中项;② 读 DFSR(0xE000ED30):等待开始前先清零(DFSR 为 W1C),命中后若 DWTTRAP(bit2) 置位即判为观察点命中,并用 DWT_COMPn 定位命中的是哪个观察点——这是硬件证据;真机实测(UVSOCK@4823 + STM32F401)本版 Keil 的 BL CNT 是断点计数条件设置值、不随命中递增,此时由 ② 接手;③ ①② 都取不到时才退化为「目标已停止 + PC 不在任何代码候选 + 存在观察点」推断为观察点命中。返回 hit_kind(code/watch)、hit_confidence(verified=有 PC/CNT/DFSR 实际证据,inferred=纯推断)、hit_entry(source 字段:pc/cnt/dfsr/inferred)、dfsr / dfsr_note(DFSR 原始值与解读)与 cnt_note(说明判定依据强度);候选来源除 symbol/address/.uvoptx 外,还包含本服务 set_watchpoint 设的数据观察点,以及在无其他候选时取 Keil 真实断点表(list_breakpoints.real)中的执行断点;若本该命中却一直不停,先用 list_breakpoints / list_uvoptx_breakpoints 确认断点存在且启用(App 侧重定位后运行时地址与符号地址不同,应传实际运行地址)。需已进入调试。另附 reset_loop 字段(批次67):同一断点在 3 秒内命中 ≥3 次时,判定「这是不是复位循环在重跑启动」——suspected=true 表示有复位证据(命中在 Reset_Handler / SP 等于向量表里的 initial SP / CYCCNT 回退),false 表示没到阈值,null 表示反复命中了但主机侧分不清复位循环与正常热循环(这时要人工核对启动时序,别硬猜)。判据来自镜像基址处的向量表(anchor 字段给出 image_base / initial_sp / reset_handler 及合法性校验)。与 repeat_warning 不是一回事:repeat_warning 说的是「同一 PC 连续出现,疑似 halt 残留值,别当反复复位看」,两者前提与结论都不同,不可互相顶替。 【参数】必填: 无;可选: symbol, address, timeout_s, poll_ms, use_project_breakpoints, project, reloc_delta 【调用示例】{} 【参数别名】symbol ← addr/expression/func/function/keyword/location/name/pattern/pc/query/target/var/variable;timeout_s(秒) ← duration/duration_ms/duration_s/max/max_ms/max_s/seconds/timeout/timeout_ms/wait/wait_ms/wait_s;poll_ms(毫秒) ← interval/interval_ms/interval_s/poll/poll_interval_ms/poll_s;带 _s/_ms 的别名按后缀换算(_s=秒、_ms=毫秒)。规范名以上方【参数】行为准;未列出的参数名会被拒绝,不会静默忽略 |
| run_timeoutA | 让目标 MCU 全速运行 timeout_ms 毫秒后自动暂停,并返回停靠位置(文件行+源码+完整调用栈)。用于验证时序 / 观察运行 N 毫秒后的状态。timeout_ms 默认 1000。时长以分段字段给出,别混用:requested_run_ms 是你请求的运行时长;actual_run_ms 是实测「run 返回 → 发 stop」的间隔(Windows 定时器粒度约 15.6ms,请求 137ms 时实测常在 140~155ms,属 sleep 精度而非工具延迟);stop_wait_ms 是 stop 之后等目标确认停止的耗时(这才是 wait_stopped.waited_ms 的含义,它与 timeout_ms 无关,不要当运行时长用);total_ms 是整次调用总耗时。halt 落点还受 UVSOCK 往返影响,毫秒级精度要求请改用 DWT 周期计数或 GPIO 打点。注意:到点 stop 后会轮询确认目标真正停止(stop 是异步生效的)才读 PC;若未能确认停止,返回 stopped=false + warning 且不返回停靠位置,避免把陈旧 PC(常量落复位附近 0x0800024c 之类)误当成停靠点。另外真机实测:halt 后首次读到的 PC 常是上一次 halt 的残留值(LR/SP 已是新值),故读取按'连续采样收敛'判定(连续两次 PC/LR/SP 一致才采纳),返回 pc_confidence=high/low;low 表示采样未收敛或复查发现目标其实仍在运行,PC 不可信,请重试。返回里始终带 pc_confidence 与 stop_verified:stop_verified=false 表示「没能确证目标已停」,此时绝不要把任何地址当停靠点(真机踩过:报出 HAL_Init / 连续同一个地址,而目标其实在跑)。若你怀疑目标没停或反复复位,请改用 wait_breakpoint(等断点命中)或 read_variable / 串口输出交叉确认。到点常停在 SysTick 等中断上下文,此时局部变量与调用栈层数可能受限/为空,AAPCS 寄存器解读不适用。需已进入调试且配置 .axf。 【参数】必填: 无;可选: timeout_ms 【调用示例】{} 【风险】中——会改变目标状态或占用共享资源(调试态/串口/Keil 实例),必要时可回退。 【参数别名】timeout_ms(毫秒) ← duration/duration_ms/duration_s/max/max_ms/max_s/ms/timeout/timeout_s/wait/wait_ms/wait_s;带 _s/_ms 的别名按后缀换算(_s=秒、_ms=毫秒)。规范名以上方【参数】行为准;未列出的参数名会被拒绝,不会静默忽略 |
| stopA | 暂停目标 MCU 的执行(进入断点/挂起状态),此时才可安全读内存/寄存器/表达式。停止是异步生效的:命令返回不代表目标已停(真机实测 stop 回 ok 后紧跟的 get_status 仍报"执行中"),这期间读到的内存/寄存器可能是脏值或陈旧值。本工具默认在 stop 之后轮询确认(verify=true),返回 stopped / stop_verified / waited_ms / state_after_stop:stop_verified=false 表示没能确证目标已停,此时不要读内存/寄存器、也不要据其下结论,可重试 stop 或稍后再读(与 run_timeout 的 stop_verified 同一口径)。verify=false 则只发命令不做确认(快,但需自行承担读到脏值的风险)。看门狗防御(真机踩过):暂停期间目标虽不跑代码,看门狗(IWDG)仍在计数——新会话/复位后 DBGMCU 冻结位会被清零,halt 超过溢出时间就被复位、RAM 现场全丢。本工具默认在 stop 后自动置位 DBGMCU 的 IWDG/WWDG 冻结位(freeze_watchdogs=true),返回 watchdog_freeze 字段供核对(含 all_frozen);不需要可传 freeze_watchdogs=false。 【参数】必填: 无;可选: verify, timeout, freeze_watchdogs 【调用示例】{} 【风险】中——会改变目标状态或占用共享资源(调试态/串口/Keil 实例),必要时可回退。 |
| resetA | 复位目标 MCU(变量回到初值、断点保留)。行为说明(真机实测,与旧描述不同):复位后目标停在复位向量、处于停止态,程序不会自行往下跑——必须再调 run(或 run_timeout / run_to_line)才会开始执行;实测复位后 get_status 返回"已停止",正因为不 run 就没有任何串口输出。返回带 state_after_reset(stopped/running)与 stopped_after_reset 说明这一点;run_after=true 可在复位成功后自动 run(等价于复位后自己再调一次 run),适合「重新跑一遍看串口输出」的场景。 【参数】必填: 无;可选: run_after 【调用示例】{} 【风险】高——不可逆:会改写目标 Flash/内存,或关闭/重启用户的 Keil 实例。执行前确认目标与工程正确。 |
| stepA | 单步执行。mode 可选:'into'(单步进入)、'over'(单步跳过)、'out'(跳出)、'instruction'(指令级)。默认 'into'。注意:单步瞬间读 PC 可能读到 SRAM 脏值(已用 FLASH 区段过滤修复)。在中断/异常 handler 内单步或 SP/LR 回溯可能层数受限;'out' 在函数入口处不可靠(Keil 可能无法正确跳出),若卡住可改用 run_to_line 跳到函数返回行。需已进入调试且配置 .axf(source 级单步)。 【参数】必填: 无;可选: mode 【调用示例】{} 【风险】中——会改变目标状态或占用共享资源(调试态/串口/Keil 实例),必要时可回退。 【参数别名】mode ← kind/over_or_into/type。规范名以上方【参数】行为准;未列出的参数名会被拒绝,不会静默忽略 |
| keil_healthA | 检查 Keil 调试通道的健康状态:UV4 进程是否存在、UVSOCK 端口是否监听、是否有模态对话框阻塞。返回 keil_alive / uv4_pids / port / port_listening / uvsock_ready / code / diagnosis / suggestion;mdkdebug_instances 给出串行化方式、并发竞争遥测(等待次数/最长等待/锁超时)与其他仍在驱动同一 UVSOCK 的 mdkdebug 进程(多个实例并存会互相穿插、静默吃掉写入,这是最隐蔽的一类故障);检测到 Keil 模态框时一并给出modal_dialogs[{title, message, button_texts}]——正文与可点按钮都有,知道框里写了什么、该点哪个(配套 dismiss_dialog 直接关框,不必再去界面手点)。用途:命令超时或「操作了没反应」时先调它,直接看清断在哪一环(keil_not_running / port_not_listening / port_occupied),而不是干等到超时;也可作为操作前后的廉价自检(纯 ctypes + socket 探测,Keil 未运行时也能正常返回)。 【参数】无(直接调用) 【调用示例】{} |
| dismiss_dialogA | 把 Keil「有个模态框在挡路」补成「框里写什么、点哪个按钮」:枚举 UV4 的模态对话框(类名 #32770),读出正文(Static 控件)与全部按钮文字(Button 控件)并按按钮点击关闭。button 传按钮文字(如「确定」「重试」,支持部分匹配);不传则按 确定/OK/是/关闭/重试 的语义顺序自动挑,没有可点按钮时退化为 WM_CLOSE。title 可按标题筛(多个框时),index 取第几个(默认 0)。返回 {ok, dismissed, clicked, method, dialog{title,message,buttons}, remaining}。用法:命令不返回且 keil_health 报 modal_blocked_suspected=true 时调它——先看 dialog.message 知道 Keil 报了什么,再决定点哪个按钮,解除阻塞后重试原命令。注意:① 关框只解除阻塞,不等于问题已修(如正文说输出文件写不进去,要先解决占用/权限);② 指定 button 却匹配不到时不会擅自改点别的按钮,而是返回 button_not_found 并列出可用按钮。 【参数】必填: 无;可选: button, title, index 【调用示例】{} 【风险】中——会改变目标状态或占用共享资源(调试态/串口/Keil 实例),必要时可回退。 |
| reset_connectionA | 只重置 UVSOCK 连接(不重启 Keil):丢弃当前 socket 与全部残留接收缓冲,下次调用自动重新建连。用于长连接会话被弄脏(调试会话残留、异步消息堆积、模态框阻塞后)导致后续命令连续超时的场景——以前只能「关掉 Keil 再开」,现在可以先用本工具原地复位;复位无效再上 restart_keil。 【参数】必填: 无;可选: reason 【调用示例】{} 【风险】中——会改变目标状态或占用共享资源(调试态/串口/Keil 实例),必要时可回退。 【参数别名】reason ← message/note/why。规范名以上方【参数】行为准;未列出的参数名会被拒绝,不会静默忽略 |
| restart_keilA | 一键重启 Keil 并重建调试通道:关闭所有 Keil 实例 → 以脱离父进程的方式重新拉起并打开工程 → 等待 UVSOCK 端口监听 → 重置连接。把「Keil 死了 / 会话脏了只能人工关掉再开」整条恢复流程变成一次调用。project 为 .uvprojx 路径(省略用默认工程);force=True 直接强制结束残留实例;wait_ready 为等待 UVSOCK 监听的秒数(默认 20)。返回各阶段结果与最终健康快照。注意:会关闭所有 Keil 实例(含人工查看中的窗口),未保存的调试会话/源码改动可能丢失,调用前请确认。 【参数】必填: 无;可选: project, force, wait_ready 【调用示例】{} 【风险】高——不可逆:会改写目标 Flash/内存,或关闭/重启用户的 Keil 实例。执行前确认目标与工程正确。 【参数别名】project ← path/proj/project_file/project_path/uvprojx;force ← hard/kill;wait_ready ← wait/wait_uvsock。规范名以上方【参数】行为准;未列出的参数名会被拒绝,不会静默忽略 |
| launch_uvisionA | 可见方式启动 Keil uVision 并打开工程,供人工查看界面 / 调试准备。project 为 .uvprojx 路径,可省略以用默认工程。reuse(默认 true):已有打开同一工程的 Keil 窗口时复用该窗口并前置,不新开——真机实测 UV4.exe 并非单实例程序,反复调用本工具会累积出多个同工程窗口(曾达 6 个),因此默认复用;确需第二个窗口时才传 reuse=false。single(默认 true)=「只保留一个 Keil 窗口」的执行者:已经开着别的工程的窗口时直接拒绝(error_code=keil-multiple-instances,返回 open_instances 与下一步),不做「偷偷关掉再开」;已经开着同工程窗口时强制复用(reuse=false 也被否决,返回 reuse_forced=true);本次没给 project 且已有实例同样拒绝(无从比对就不猜)。确实要同时开多个窗口才传 single=false。返回值含 reused / pid / instances(当前同工程窗口数)。用户无需手动打开 Keil,AI 可通过本工具拉起;想看当前开了几个窗口用 list_uvision_instances,想把多余的收掉用 close_uvision(keep="latest")。uvsock_port:传端口号则给这次启动加官方开关 |
| batch_debug_scriptA | 用 Keil 官方命令行批处理通道跑一段固定的调试脚本:
|
| list_uvision_instancesA | 列出当前所有 Keil uVision 实例:PID、启动时间、打开的工程、是否有窗口。用于确认是否残留了多个同工程窗口——UV4.exe 并非单实例程序,反复 launch_uvision / flash_debug 会累积实例而互不回收(真机上曾同时开着 6 个同工程窗口)。project 可选:只统计打开该工程的实例。count>1 时返回 note 提示收敛方式。收敛为一个窗口:close_uvision(keep="latest")。 【参数】必填: 无;可选: project 【调用示例】{} 【参数别名】project ← path/proj/project_file/project_path/uvprojx。规范名以上方【参数】行为准;未列出的参数名会被拒绝,不会静默忽略 |
| close_uvisionA | 关闭 Keil uVision 实例,配合 launch_uvision 实现 Keil 开关闭环。keep="all"(默认)关闭全部实例;keep="latest" / "oldest" 只保留一个实例(最新 / 最早启动的那个),其余关闭——用于把累积的多个同工程窗口收敛成一个,只开一个窗口调试。project 非空时只处理打开该工程的实例。force 默认 False:先优雅关闭(发送关闭消息),残留则自动强制终止;force=True 直接强制结束。返回 closed / kept / total_before / remaining。注意:会关闭 Keil 窗口(含人工查看中的),调用前确认无需保留。强制终止后立即重取进程列表可能短暂误报残留(本工具已轮询等待)。沙箱环境受权限/跨会话限制可能无法关闭,需在真实运行环境使用。 【参数】必填: 无;可选: force, keep, project 【调用示例】{} 【风险】高——不可逆:会改写目标 Flash/内存,或关闭/重启用户的 Keil 实例。执行前确认目标与工程正确。 【参数别名】force ← hard/kill;project ← path/proj/project_file/project_path/uvprojx;keep ← keep_one/keeponly/retain。规范名以上方【参数】行为准;未列出的参数名会被拒绝,不会静默忽略 |
| target_infoA | 查询目标芯片信息:实时读 DBGMCU->IDCODE 寄存器得到 DEV_ID/REV_ID 并映射到型号,返回标称 Flash/RAM 容量与内存布局。排查“资源吃紧/选错型号/容量不符”时先调它。idcode 实时读取需已进入调试(内存读依赖调试会话);非调试态仅返回静态布局信息。注意:DEV_ID = IDCODE 低12位(&0x0FFF)、REV_ID = 高16位、IDCODE 为小端字节序(本工具已正确解析);实时读 IDCODE 需已进入调试,非调试态仅返回静态布局信息。未收录型号返回标称容量 None + 提示按丝印确认。 【参数】无(直接调用) 【调用示例】{} |
| mdk_guideA | AI 落地的第一个工具:一键自检 Keil/UVSOCK/UV4/.axf/源码漂移/调试态/RTOS 类型,并返回推荐的调试工作流与各场景应调用的工具,避免 AI 盲目试错。返回 {environment:{...}, recommended_workflow:[...], scene_tools:{...}}。注意:建议 AI 落地第一件事先调本工具获取环境自检与工作流,再按场景选择工具;自检为无副作用只读操作,可在任意时刻调用。topic=tool, name=<工具名> 取回该工具被挪出上下文的完整说明(为省上下文,长描述在工具列表里只留一句话摘要,正文全文存在这里);topic=tool 不带 name 则列出全部已归档工具与描述档位。 【输出控制】本工具返回体可能较大,额外接受三个可选参数:compact=true(精简)/ max_lines=N(限制列表条数)/ full=true(强制全量)。默认都不传=行为不变;被裁掉的内容一定会在返回体的 output 字段里如实上报(truncated/dropped/trimmed/hint),不会静默丢数据。也可用环境变量 MDKDEBUG_COMPACT=1 / MDKDEBUG_MAX_LINES=N 设全局默认。 【参数】必填: 无;可选: topic, name, compact, max_lines, full 【调用示例】{} |
| wait_stateA | 轮询等待目标进入某个状态,把「等待 + 超时 + 现场」三件事一次做完,省掉 AI 自己 sleep + get_status 的轮询循环(那种循环既慢又容易在超时后不知道现场是什么)。state 取值: |
| capabilitiesA | 冷启动第一步的能力自检:一次看清这台上有什么可用、以及每条通道当前通不通,避免 AI 拿不存在的功能去试错。返回四块:
|
| session_stateA | 把「这次调试是怎么配起来的」落盘成 state.json,供下个会话接续,解决 MCP 工具无状态、会话一断上下文全丢的问题(最典型的是符号文件漂移:接着上次调试却加载了别的 .axf,表达式集体解析失败)。记录内容:默认工程、符号文件、调试会话标记、内部断点/数据断点清单、串口端口与波特率、SVD 器件、snapshot_diff 基线等。action:show(默认,看当前上下文与磁盘态差异)/ save(落盘,旧文件自动备份为 .bak)/ load(读回;apply=true 才执行可恢复动作)/ clear(删除,需 confirm=true)。两条约定:① 只存观察到的,采不到的字段标 available=false 与原因,不填默认值假装成功;② load 默认只对比不应用,apply=true 也只恢复主机侧可逆项(目前仅符号文件切换),断点/内存/运行态等目标侧状态永不自动重放。路径可用 path 指定,或用环境变量 MDKDEBUG_STATE_FILE,默认 ~/.mdkdebug/state.json。 【输出控制】本工具返回体可能较大,额外接受三个可选参数:compact=true(精简)/ max_lines=N(限制列表条数)/ full=true(强制全量)。默认都不传=行为不变;被裁掉的内容一定会在返回体的 output 字段里如实上报(truncated/dropped/trimmed/hint),不会静默丢数据。也可用环境变量 MDKDEBUG_COMPACT=1 / MDKDEBUG_MAX_LINES=N 设全局默认。 【参数】必填: 无;可选: action, path, apply, confirm, compact, max_lines, full 【调用示例】{} 【风险】中——会改变目标状态或占用共享资源(调试态/串口/Keil 实例),必要时可回退。 |
| toolsetA | 本服务的工具按 11 个组划分,另有一个 nano 极简档(只暴露十几个最短入口),默认只暴露 core 组(调试核心 + 环境引导),其余组用到时现装——这样上下文里只放当前真正用得上的工具描述,工具多的时候这是省上下文的主要手段。action=status 看当前暴露了哪些组、各组多少个、还差什么;action=load 把 toolsets 指定的组装回来(例:toolsets=mem,trace,toolsets=all 一次全装,toolsets=nano 极简);action=unload 把某组收起来(例:toolsets=trace)。可用组与含义:core 调试核心/引导、mem 内存进阶、symbol 符号反汇编、build 编译烧录、serial 串口、advanced 异常/watch/SVD、toolchain 非MDK构建、target 目标档案、ocd OpenOCD、trace SWO/RTT/变量时间线、rtos 任务感知。装卸后工具面立即变化,但很多 MCP 客户端缓存了工具列表:若装完仍报未知工具,先重新拉一次 tools/list 再调。list_tools / get_version / capabilities / toolset 这四个永远保留。小上下文模型:先 tools_groups() 看有哪些组,再 tools_load(group=...) 现装;或直接以 MDKDEBUG_TOOLSETS=nano 启动,只暴露十几个最短入口。 【参数】必填: 无;可选: action, toolsets 【调用示例】{} 【风险】中——会改变目标状态或占用共享资源(调试态/串口/Keil 实例),必要时可回退。 |
| tools_groupsA | 列出工具分组(含 nano 极简档)与当前是否已装进上下文。group 留空给总览;给了组名则列出该组工具名。小上下文模型从这里挑组,再 tools_load(group=...) 装上。 【参数】必填: 无;可选: group 【调用示例】{} |
| tools_loadA | 把 group 指定的组装进工具面(unload=true 则收起)。group 可写单个组名、逗号分隔多个、或 all / nano。装完若客户端仍报未知工具,重新拉一次 tools/list(客户端会缓存工具列表)。 【参数】必填: 无;可选: group, unload 【调用示例】{} 【风险】中——会改变目标状态或占用共享资源(调试态/串口/Keil 实例),必要时可回退。 |
| list_toolsA | 一次列出本服务的全部工具:名称、用途、必填/可选参数与最小调用示例(example_args 可直接照抄成 args)。AI 冷启动、或不确定某工具准确参数名时先调它——本服务的参数命名不统一(有 query/expr/addr/n_bytes 等),只靠 'Field required' 报错试错代价高;这里一次就能对齐。keyword 按工具名或用途子串过滤(如 keyword="breakpoint"、"mem"、"断点"),留空返回全部。 【输出控制】本工具返回体可能较大,额外接受三个可选参数:compact=true(精简)/ max_lines=N(限制列表条数)/ full=true(强制全量)。默认都不传=行为不变;被裁掉的内容一定会在返回体的 output 字段里如实上报(truncated/dropped/trimmed/hint),不会静默丢数据。也可用环境变量 MDKDEBUG_COMPACT=1 / MDKDEBUG_MAX_LINES=N 设全局默认。 【参数】必填: 无;可选: keyword, compact, max_lines, full 【调用示例】{} 【参数别名】keyword ← filter/name/query/search。规范名以上方【参数】行为准;未列出的参数名会被拒绝,不会静默忽略 |
| view_renderA | 把已有的采集结果渲染成一个可交互的单文件 HTML(深色主题、可缩放/平移/回放),给人看「问题出在哪、场景长什么样」——不必再手写网页。渲染层是固定的:同一类数据画出来长得一样,看图的人不用每次重新适应。
最常用的一步调用:把采集工具的返回原样丢进 |
| view_guideA |
|
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 44 tools
绝大多数工具都有清晰不同的目标,例如 set_breakpoint、clear_breakpoint、list_breakpoints 分别独立;但存在少量概念重叠,如 read_console_output 与 read_async_messages、calc_expression 与 read_variable、wait_breakpoint 与 wait_state,不过描述中明确区分了它们各自的适用场景。keil_command 作为通用后备工具,覆盖范围广,但被定义为万能的兜底,所以整体仍可区分。
工具名称基本遵循 动词_名词 的下划线风格,如 set_breakpoint、list_symbol_projects、enter_debug 等,但存在少量例外,如 keil_command、env_check、mdk_guide 没有严格的动词前置,命名风格略有混用。总体一致,没有大小写混淆,可读性好。
44 个工具数量明显偏多,超出了建议的 3-15 个常规范围,但服务器提供了工具分组机制(core、mem、symbol、serial 等)和按需加载工具(toolset、tools_load),以减轻上下文负担。考虑到涉及 Keil 调试的全面功能(会话、内存、符号、断点、Keil 管理、批处理等),该数量还算契合整体目的,但仍有精简空间。
该工具面覆盖了嵌入式调试的完整生命周期:调试会话管理(enter/exit/run/stop/step/reset)、内存和变量读写(read_mem、write_mem、calc_expression、read_variable)、断点操作(set/clear/list/all-clear)、符号文件管理(set_symbol_file、list_symbol_projects)、诊断聚合(diagnose、env_check、target_info)、Keil 实例管理(launch/close/restart/health)、批处理执行以及会话持久化(session_state)。没有明显缺失的关键操作。