news 2026/9/8 17:36:24

用Claude Code Skill打造嵌入式AI管家:编译、烧录到波形分析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用Claude Code Skill打造嵌入式AI管家:编译、烧录到波形分析

1. 为什么说嵌入式开发终于等来了“AI 管家”

干嵌入式这行的人都有个共同感受:**这边的工具链太散了。**写代码用 VSCode,编译靠 CMake 加交叉编译器,烧录要敲 OpenOCD 命令,查寄存器得翻 datasheet,看波形又要切到逻辑分析仪的软件里。一天下来真正写代码的时间没多少,全在工具之间来回切换、查资料、填参数。尤其是调试阶段,CPU 跑到哪个寄存器、哪个外设没初始化对、波形时序差了几个微秒——这些问题靠肉眼盯屏幕找,真的是在拿命换效率。

Claude Code 本身的写代码能力大家已经见识过了,但把它用在嵌入式上,一开始我也只是让它帮忙生成点驱动的框架代码。真正让我觉得“有戏”的,是 Claude Code 的 Skill 机制。Skill 说白了就是一套高度定制化的指令包和工具集合,你把编译脚本、烧录流程、寄存器映射表、波形解析脚本都整理好,Claude 按你设定的流程来调。它就不再是一个等问题的问答机器人,而是一个能自己跑通“编译错误→拿日志→查代码→改完再编译”这条闭环的干活搭档。

所以这篇文章我就把这段时间摸出来的经验完整梳理一遍。适合的人大概是这几类:一是被 Keil、IAR 绑住手脚、想换成现代工作流又不确定怎么落地的 MCU 开发者;二是已经在用 Claude Code 写业务代码、正准备往嵌入式方向延伸的 AI 编程重度用户;三就是纯粹好奇“AI 能不能替我看时序图”的硬件工程师。我会把 Skill 怎么设计、怎么注册、各个功能模块怎么实现讲清楚,尽量少讲套话,多给能直接抄走的配置和脚本。

2. Skill 的架构设计:先想清楚 Claude 到底“会做”什么

2.1 嵌入式 Skill 不能只给提示词

不少人以为 Skill 就是写一段“你是一个嵌入式专家”的提示词,这是个误区。Claude Code 的 Skill 机制分为两部分:SKILL.md 指令文件可执行的工具脚本。指令文件负责告诉模型“在什么场景下调用、遵循什么样的步骤”,而工具脚本是真正干活的实体,负责编译、烧录、抓寄存器值这类操作。

我第一版只写了 SKILL.md,让 Claude “根据交叉编译器执行编译”,结果它自作聪明地调用了一个并不存在的编译器路径,报错之后还一脸无辜。后来我把编译脚本写成 Python 文件,让 SKILL.md 里面明确写“调用 tools/build.py,参数为 board_type 和 target”,情况才稳定下来。这个教训是:Skill 的本质是把人类工程师的工作流固化成代码,而不是靠模型临场发挥。模型的优势在判断日志、分析错误、规划修复方案,而不是在一个陌生的嵌入式环境中摸索路径。

2.2 分层结构:指令、工具、数据源

我现在用的嵌入式 Skill 目录大概长这样:

embedded_skill/ ├── SKILL.md ├── tools/ │ ├── build.py │ ├── flash.py │ ├── read_reg.py │ └── parse_wave.py ├── configs/ │ ├── stm32f407.json │ └── esp32c3.json └── docs/ └── register_map.md

SKILL.md 是入口,描述技能的使用场景、边界和流程。tools 里面的脚本是能执行的动作,configs 保存不同板子的编译参数和烧录接口,docs 放一些参考备忘,比如寄存器地址和位的含义、波形数据格式约定。

这个分层的好处是职责清晰:Claude 负责根据对话上下文决定调哪个工具、怎么解释工具输出,但工具本身不依赖 Claude 的“智商”。即使某天没有模型参与,你自己命令行也能跑这些脚本。这样等于把 AI 的可控性建立在了确定性代码之上。

2.3 场景触发条件要尽量明确

SKILL.md 里面我专门写了触发条件,避免 Claude 在写算法题的时候也莫名其妙去加载嵌入式工具链。现在设置的触发场景有这么几类:用户在对话里提到具体的芯片型号,比如 STM32F407、ESP32-C3;提到编译、烧录、寄存器、波形这些关键词;或者直接将项目根目录指向一个带 CMakeLists/Makefile 的嵌入式工程。只有这些条件被满足时,Skill 才会激活。

这样一个设计思路,核心其实是资源聚焦。嵌入式相关的工具链、数据文件、脚本如果全部常驻在上下文里,会占用大量 token,导致模型在普通代码任务上的表现也会变差。靠场景触发来按需加载,能有效控制开销,这也是 Skill 机制和普通自定义 system prompt 的一个重要区别。

3. 搭建自己的嵌入式 Skill 环境

3.1 准备工具链和基础依赖

在写任何 Skill 代码之前,先把开发环境本身彻底搞定。因为 Skill 只是帮你更高效地调用工具,不能替代工具本身。我目前的工作环境是 Windows + WSL2,Windows 侧跑串口终端和图形化的逻辑分析仪客户端,Linux 侧放交叉编译器和自动化脚本。

必备的东西列一下:

  • Claude Code CLI,这个直接 npm 安装就行,装完claude命令能正常响应。
  • 交叉编译链,ARM 系列用arm-none-eabi-工具链,ESP32 用乐鑫官方的idf.py工具链。
  • CMake 和 Ninja,用来驱动构建系统,Ninja 的增量编译速度比 Makefile 快很多。
  • OpenOCD 或者 stlink-tools,用于烧录。OpenOCD 兼容性好,如果需要用 J-Link,则装好 J-Link 驱动,命令行工具是JLinkExe
  • Python 3.10 以上,用来写各个工具脚本,顺便处理波形文件。

这些准备好之后,先手动验证一遍命令能跑通,再接入 Skill 层。不然你让 Claude 调一个本来就不好使的脚本,它会陷入无意义的反复尝试,很浪费时间。

3.2 配置 SKILL.md:让 Claude 明白自己的工作边界

SKILL.md 就是给 Claude 看的一份“工作岗位说明书”。我自己的写法分四块:

第一块是技能描述,一句话说明这个 Skill 服务于嵌入式 MCU 开发,覆盖哪些阶段。第二块是触发条件,就是前面说的场景关键词。第三块是工作流定义,规定当用户提出需求时,Claude 必须先分析需要哪些工具,再按顺序执行,最后汇总结果。比如用户说“编译一下”,Claude 应该:读取项目配置,调用 build.py,检查返回码,如果失败就分析日志、定位文件、给出修改建议。

第四块是安全护栏,这条很重要。我明确写了:涉及芯片寄存器的写入操作,必须经过用户明确确认才可以执行;烧录命令默认不添加擦除全片之类的危险操作;如果脚本输出编码异常或者命令找不到,不要假装成功,必须如实反馈。

这里贴一个精简版的 SKILL.md 开头部分,大家可以参考它的结构:

--- name: embedded-assistant description: 嵌入式MCU项目开发助手,负责编译、烧录、寄存器调试和波形分析。 --- # Embedded Assistant Skill ## 触发条件 - 用户提到具体芯片型号,如 STM32、ESP32、GD32、NXP 系列 - 用户提到编译、烧录、寄存器、波形、linker、MAP 文件等关键词 - 当前工作目录存在 CMakeLists.txt、Makefile、*.ioc、platformio.ini 等嵌入式工程文件 ## 工作流程 1. 询问或确认目标板型、编译环境 2. 从 configs/ 下加载对应板型的配置文件 3. 根据用户意图调用 tools/ 下的功能脚本 4. 分析输出,给出结论或修复建议

3.3 注册 Skill 到 Claude Code

Claude Code 的 Skill 是通过目录约定来识别的。把embedded_skill/整个文件夹放到指定的 skills 目录下后,在会话中用@embedded-assistant就能加载。如果希望某些场景自动触发,可以在项目级的 CLAUDE.md 中写上关联说明。

先在一个空目录里做一个最小化实验:让 Claude 读取 SKILL.md,然后问它“如果用户说编译失败了,你该怎么做”。正常的话,它会按照工作流程描述,先定位配置文件,再看日志,而不是直接给你乱写一段代码。这一步通过了,说明 Skill 注册成功,接下来往里面加功能模块才有意义。

4. 四大核心功能实现:从编译到波形

4.1 编译模块:最基础也最容易出错

编译模块在整个 Skill 里的位置是“地基”。如果编译这一步不可靠,后面不管查寄存器还是看波形,都是空中楼阁。

我的 build.py 主要逻辑是:读取目标板子配置文件,确定编译工具链路径和 CMake 参数;调用 subprocess 启动构建;捕获 stdout 和 stderr;判断返回码;如果失败,把错误段落保留下来供 Claude 分析。

配置文件的格式大致如下:

{ "board": "stm32f407", "toolchain": "arm-none-eabi-", "cmake_options": ["-DCMAKE_BUILD_TYPE=Debug", "-DCMAKE_TOOLCHAIN_FILE=toolchain.cmake"], "build_dir": "build/stm32f407", "output": "build/stm32f407/firmware.elf" }

这里有个很关键的细节:Claude 分析编译错误时,最好把错误信息包含的具体文件路径和行号完整保留,不要只给一个错误类型。因为嵌入式编译报错经常是连锁反应——一个头文件路径写错,会带出几百行莫名其妙的类型错误。如果只把错误摘要给模型,它会盯着后面那些衍生错误浪费时间。比如原来的代码里写错了寄存器地址偏移,编译器报了 “undefined reference to xxx”,如果不看 MAP 文件,只从语法上找问题,根本定位不了。

所以我在 build.py 里做了个额外处理:错误信息先按“文件路径”和“错误关键字”分组,提取出每个文件的核心错误行,再交给 Claude。这样模型拿到的信息密度高,定位问题的速度会快很多。实测下来,原本人工要看半天的编译错误,交给 Skill 流程后往往几分钟内能指出是哪个源文件的哪个宏定义有问题。

4.2 烧录模块:让 AI 操作你的开发板

烧录部分我保持了比较保守的策略。flash.py 会先显示将要执行的命令和操作说明,并且支持--confirm参数来控制是否需要人工确认。在实际使用中,我会让它默认开--confirm,哪怕 Claude 已经觉得没问题了。

烧录脚本里面做了一个“先查询后操作”的流程:先查询当前连接的调试器或串口设备,识别芯片型号,再确定烧录方式。比如 STM32 常用 ST-Link,走 OpenOCD;ESP32 常用 USB 转串口,走 esptool。每次烧完,我要求脚本自动执行一次校验读取,确认 Flash 内容和构建产物一致。

这里有一个我在实际中反复踩到的坑:WSL2 对 USB 设备的转发支持并不总是顺畅。经常出现烧录器在 Windows 侧认到了,但 WSL2 里面 lsusb 看不到设备。解决方案是把 Windows 侧的烧录工具做成一个代理,WSL2 里的脚本通过 socket 或者简单 HTTP 调用 Windows 侧的命令行工具。这样既保留了 WSL2 的编译优势,又能正常操作硬件。这个问题在社区里问的人很多,建议大家提前规划好接线方式,避免在 Skill 调试阶段被环境问题卡住。

烧录完成之后,“AI 管家”还能干一件事:自动检查程序入口函数是否被正确放置。检查方式是用arm-none-eabi-objdump看反汇编入口地址,或者直接读取 MAP 文件的入口符号,如果发现入口偏移不对,说明链接脚本有隐患。这个检查项也是我在实际项目中加进去的,最初是因为一次 Bootloader 跳转失败,查了两天才定位到链接脚本里 vector table 对齐没写对。

4.3 寄存器查看模块:把 800 页 datasheet 变成一问一答

寄存器模块是 Skill 中最接近“管家”定位的功能。嵌入式开发里查寄存器太常见了,常见到什么程度——“这个位是干嘛的来着?”“为什么我改了配置没生效?”“这个寄存器是只读的吗?”这类问题在调试的时候几乎每隔十几分钟就会冒出来一次。以前大家的做法是翻 datasheet,在几百页 PDF 里面搜关键词,效率极低。

我的实现思路分成两路:一路是代码层面的寄存器定义查询,另一路是运行时寄存器值读取

代码层面的查询,核心是一个寄存器描述文件。我用表格形式把常用外设的关键寄存器整理好,放到 docs/ 目录下面。比如 GPIO 的 MODER、OTYPER、OSPEEDR、PUPDR、IDR、ODR,UART 的 BRR、SR、DR,定时器的 CR1、CCMR1、CCR 等。每一条都写明偏移地址、复位值、每个位的含义、典型配置值。Claude 读这个文件之后,可以解释一段代码在操作什么、配置结果会是什么。

运行时的寄存器读取,我写了一个 read_reg.py。早期版本是通过 OpenOCD 的mdw命令直接读内存地址,这样做很直接,但不区分外设总线。后来发现外设基址在不同系列芯片上差异很大,于是改成先用配置文件获取总线基地址,再算出绝对地址来读。现在还可以通过 gdb 的x/wx命令来做,但 gdb 需要额外跑一个 gdbserver,配置成本高了一些。

read_reg.py 的一个额外功能是把寄存器的值解释成有意义的文本。比如读取一个 16 位的状态寄存器,脚本会按每个标志位的掩码拆开,标出哪个位是 1、表示什么状态。Claude 基于这个输出就能直接判断外设是否工作正常,不需要用户再对着十六进制数心里默算。比如以太网 PHY 的寄存器分析,靠这个脚本读几个关键寄存器,基本能判断出 link 状态、协商速率和工作模式有没有异常。

4.4 波形分析模块:让 Claude 帮你看时序图

波形分析这块是很多人觉得最像“黑科技”的部分,其实原理并不复杂。逻辑分析仪导出的文件格式一般是 CSV 或者 VCD,CSV 是一条条数据样本,VCD 是带时间戳的信号电平跳变记录。我的 parse_wave.py 就是把这两种格式解析成结构化的时序描述,再交给 Claude 去做高层推理。

比如一个 I2C 的波形解析流程是这样的:

  1. 读取 CSV 文件,识别 SCL 和 SDA 两路信号。
  2. 根据 SCL 上升沿的位置截取 SDA 的电平状态,组装成一串字节序列。
  3. 判断起始条件(SCL 高电平时 SDA 从高变低)和停止条件(SCL 高电平时 SDA 从低变高)。
  4. 把字节序列翻译成 I2C 地址、读写位、数据和 ACK/NACK 状态。
  5. 输出完整的时序描述文本,交给 Claude 进一步分析。

Claude 拿到这段描述后,能做的事情就多了。比如 I2C 地址不对,它能指出设备的 7 位地址和 8 位地址之间的区别;比如有 NACK,它可以根据代码逻辑判断是设备没上电还是地址写错。这种能力对硬件调试帮助极大,因为传统的逻辑分析仪软件只能给出“波形长这样”,而我们需要的是“波形说明了什么”。

用 CSV 做解析的一个大坑是采样率不足。如果你用低采样率的逻辑分析仪去抓高速 SPI,很容易出现信号跳变没有被捕捉到的情况,解析出来的总线数据完全是错的。我现在的处理方式是:在文件头部记录采样率,解析之前先检查信号最高频率和采样率之间的关系,如果采样率低于信号频率的 8 倍,就给出警告提示数据可能不可靠。这个小提示曾经帮我避免了一次很尴尬的误判:代码逻辑没问题,是逻辑分析仪采样率等级设置低了,信号边沿被平滑掉了。

5. 实操中遇到的几个典型问题和解决思路

5.1 Claude 调用了错误的编译器或者路径

这个错误出现的场景一般是切换了项目,但配置文件没有同步更新。Skill 记住了上一个项目的工具链路径,却在新的芯片平台上执行。我的解决办法有两个:一是配置文件中加入 toolchain 的 MD5 校验或者版本检查,二是让 build.py 检测到编译器不存在时,主动输出一份“可用编译器列表”而不是直接报错。这样 Claude 就能根据提示自己切换工具链,而不是反复尝试一个不存在的路径。

5.2 寄存器查询结果与实际不符

有段时间 read_reg.py 读出来的寄存器和 IDE 里看到的完全对不上,排查下来发现是芯片在低功耗模式下,部分外设时钟被关闭,读寄存器会返回全 0 或伪随机值。现在脚本里加了一个前置检查:先确认目标外设的时钟是否使能,如果未使能,不再无脑去读值,而是提示用户“当前外设时钟关闭,寄存器读取结果无意义”。这个细节看着小,实际调试时非常能节省时间。

5.3 波形文件太大导致解析超时

逻辑分析仪抓一次几秒的数据,CSV 文件可能到几百 MB。直接让 Python 一次性读入内存,脚本直接卡死。我现在改用分块读取的方式,只提取用户关注时间段的数据。同时允许用户在对话里指定采集通道和时间范围,把数据量降下来。这个优化让波形解析从“不可用”变成了“日常可用的工具”,也是我觉得最值得做的一个工程化改进。

6. 这套方案到底有多大价值:效率对比和心得

从半个月的实际使用体验来看,我统计的大致效率变化是:常规编译错误定位时间从以前的 15 到 30 分钟,降到现在的 3 分钟以内;查寄存器配置,以前要翻 datasheet,现在直接问一句“这个寄存器的这个位是什么意思”就能得到带上下文的解答;烧录流程因为加了自动校验,基本能做到一次成功。最明显的感受是,调试心态变了。以前遇到复杂 bug,第一反应是“有点慌,又要查半天”,现在是“先让 Claude 跑一遍工具流程,看看数据说是怎么回事”。

不过也想提醒一句:当前这个“AI 管家”距离全自动还远。它的判断能力仍然是概率性的,尤其是在极端边界条件下,比如 DDR 时序异常、电源纹波导致的偶发复位这类硬件深水区问题,AI 也只能帮你缩小范围,最终定论还是得靠你手里的示波器和经验。但作为嵌入式开发者的日常助手,这个 Skill 的价值已经能明显感知到了。

我目前把 compile 和 register 这两个模块用得很熟,波形模块在 I2C、SPI、UART 这类低速总线上已经足够可靠。下一步计划是把 RTOS 的任务调度状态也纳入进来,让 Claude 能通过读内核数据结构来回答“这个任务为什么没被调度到”这类问题。这个做完之后,嵌入式调试中最后一个难啃的硬骨头——实时系统问题,也就有了 AI 辅助的切入点了。

最后再分享一个小技巧:Skill 的配置目录建议放进 git 仓库里管理,每次调整工具的阈值、更新寄存器描述文件,都留下提交记录。Claude 在分析问题的时候,你甚至可以问它“这个脚本最近改了什么”,它能通过 git 历史帮你快速回溯变更。这个用法是我在整理波形解析脚本时偶然发现的,目前已经成为我的日常操作之一,强烈推荐给打算长期维护这套 Skill 的人。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/8 17:35:57

基于光伏出力利用率的充电站能量调度策略与工程实践

给充电站装光伏,听起来是一笔稳赚的账:白天阳光最猛的时候正好是工商业电价的高峰,光伏发的电直接充进车端,每一度电都省下了从电网买电的钱。可真到现场盯过三个月,你会发现“光伏好、充电需求也好”的日子只存在于PP…

作者头像 李华
网站建设 2026/9/8 17:35:10

pot-desktop:跨平台划词翻译与截图 OCR,三端一条命令装好

pot-desktop:跨平台划词翻译与截图 OCR,三端一条命令装好 【免费下载链接】pot-desktop 🌈一个跨平台的划词翻译和OCR软件 | A cross-platform software for text translation and recognition. 项目地址: https://gitcode.com/GitHub_Tren…

作者头像 李华
网站建设 2026/9/8 17:34:30

RK3588 别再用一个JSON走天下了-边缘AI配置体系这么搭

RK3588 别再用一个 JSON 走天下了,边缘 AI 配置体系这么搭很多做边缘 AI 设备的团队,把精力全放在算法和性能上,配置体系却是一个 config.json 塞到底。开发阶段没问题,一到量产和运维阶段,问题全来了: &am…

作者头像 李华
网站建设 2026/9/8 17:33:56

国产工业相机高端破局:从线扫到大面阵,埃科光电如何突围

1. 高端机器视觉的牌桌上,国产厂商拿到了什么底牌聊工业相机,很多人的第一反应还是Basler、海康,或者再往上一点想到德国、日本的那些老牌光学大厂。这种认知惯性可以理解,毕竟过去十年里,产线上跑得最稳的确实是进口设…

作者头像 李华