ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

嵌入式开发效率低?用Claude Code打造AI编程工作流

嵌入式开发效率低?用Claude Code打造AI编程工作流 嵌入式开发这个圈子有个挺有意思的现象大家愿意花一整天调一个I2C时序却不太愿意花半小时把开发环境理顺。我见过太多人Keil、IAR、CubeIDE装了一堆编译脚本手写、单元测试靠人肉点、代码review全靠肉眼扫然后抱怨嵌入式效率低。其实这两年AI编程工具已经悄悄渗透进嵌入式领域了只是大部分人还停留在AI能帮我写个for循环的认知层面。Claude Code是我在嵌入式项目里用得最顺手的一个CLI形态AI编程工具。它不像IDE插件那样绑死在某个编辑器上而是直接跑在终端里能读你的工程目录、能执行命令、能改文件、能跑测试。对于嵌入式这种工程结构复杂、构建链路长、跨平台编译常见的场景CLI形态反而比GUI更合适。这篇就聊聊我在Linux和Windows两套环境下把Claude Code跑起来、配好、并且真正用进嵌入式工作流的完整过程包括那些官方文档不会告诉你的坑。1. 为什么嵌入式场景值得单独折腾一个CLI编程工具1.1 嵌入式工程的目录结构决定了GUI工具的天花板做过嵌入式的人都知道一个中等规模的固件工程长什么样顶层是CMakeLists或者Makefile下面按BSP、HAL、Middleware、Application分层每层又有自己的子目录和构建脚本交叉编译工具链的路径写在环境变量或者toolchain file里链接脚本、启动文件、寄存器定义头文件散落在各个角落。这种结构用IDE打开索引能跑十分钟改一个宏定义要等半天重新解析。Claude Code的工作方式不一样。它不建索引而是按需读取——你让它看某个文件它才去读你让它找某个符号在哪定义它用grep和find去搜。这意味着面对一个几万行的嵌入式工程它的响应速度不会因为工程规模而线性下降。我在一个基于STM32H7的项目里试过工程大概四万多行C代码加一堆汇编启动文件Claude Code定位一个中断向量表的定义大概两三秒比IDE的全局搜索还快。更重要的是嵌入式工程经常有同一份代码要适配多个硬件版本的情况用宏开关控制。这种代码在IDE里跳转经常跳错分支而Claude Code可以直接读条件编译的上下文理解当前配置下哪段代码是激活的。1.2 CLI形态天然适配交叉编译和远程开发嵌入式开发有个绕不开的场景代码在Linux服务器上编译硬件在另一台机器上烧录开发者在Windows上写代码。这种三地分离的布局GUI工具很难处理但CLI工具天然就是为这种场景设计的。Claude Code跑在终端里意味着你可以SSH到编译服务器上直接用也可以在本地WSL里跑还可以在Windows的PowerShell里跑。它执行的所有命令都在当前shell环境里交叉编译工具链的PATH、CC、CXX这些变量它都能直接继承。我现在的习惯是在WSL里跑Claude Code工程挂载在/mnt/d/workspace下面编译用arm-none-eabi-gcc烧录用openocd整个链路Claude Code都能直接调用。这里有个细节值得说Claude Code执行命令时是真实调用系统的shell不是模拟的。所以你在工程里配的pre-build脚本、post-build脚本它都能触发。这一点比很多沙箱式的AI工具强太多那些工具跑在一个隔离环境里根本碰不到你的工具链。1.3 嵌入式单元测试的痛点正好是AI工具的强项嵌入式单元测试是个老大难。PC上跑单元测试容易但嵌入式代码大量依赖寄存器操作、中断、硬件外设直接拿到PC上跑会段错误。常见的做法是做硬件抽象层HAL把寄存器操作封装成可mock的接口然后用Unity、CMock、Ceedling这套框架在PC上跑测试。问题是写mock和写测试用例本身就很费时间。一个中等复杂度的驱动模块写测试的时间可能是写驱动本身的两三倍。Claude Code在这件事上的价值在于它能读你的驱动代码理解接口然后帮你生成mock框架和测试用例的骨架。我实测下来一个I2C传感器的驱动让它生成CMock的mock配置和一组边界测试用例大概能省掉六七成的手工劳动。当然生成的用例需要你review和补充但骨架搭起来之后填充具体断言就快多了。2. 安装前的环境盘点Node.js、包管理器和终端选择2.1 Node.js版本这件事比想象中重要Claude Code是基于Node.js的CLI工具通过npm分发。这里第一个坑就是Node.js版本。官方要求Node 18以上但我实测下来Node 18在部分Linux发行版上会有依赖解析的警告Node 20 LTS是最稳的。如果你系统里已经有Node先跑一下node -v npm -v如果版本低于18别急着升级系统自带的Node因为很多Linux发行版的包管理器里的Node版本是跟系统组件绑定的直接升级可能搞坏其他东西。推荐用nvmNode Version Manager来管理curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash source ~/.bashrc nvm install 20 nvm use 20 nvm alias default 20Windows用户如果不想折腾WSL可以直接去Node.js官网下LTS版本的安装包一路下一步就行。但我要提醒一句Windows原生环境下跑Claude Code路径分隔符和shell命令的差异会带来一些麻烦后面会细说。2.2 npm源的问题在国内环境下必须处理这个不用回避国内直连npm官方源速度确实不行装Claude Code这种依赖比较多的包经常卡在某个依赖上下不来。解决办法是换源npm config set registry https://registry.npmmirror.com换完之后验证一下npm config get registry应该输出你设置的镜像地址。这里有个经验如果你公司内网有自己的npm私服优先用私服因为私服通常还代理了其他内部包混用公网源和私服容易出依赖冲突。2.3 终端的选择直接影响使用体验Claude Code是个交互式CLI终端的选择会影响体验。Linux和macOS上默认终端基本都能用但我推荐用tmux或者zellij这类终端复用器因为Claude Code跑长任务的时候你可能会想切出去干别的。Windows上情况复杂一些。PowerShell能用但有几个问题一是中文显示偶尔会乱码需要设置chcp 65001二是某些Unix风格的命令比如grep、find在PowerShell里行为不一致。我的建议是Windows用户优先用WSL2在WSL里跑Claude Code工程目录通过/mnt挂载。这样既保留了Windows的图形界面又有了Linux的完整shell环境。如果你坚持用Windows原生环境那至少装个Git BashClaude Code在Git Bash里的表现比在PowerShell里稳定。3. Claude Code的安装过程与首次启动配置3.1 全局安装与版本锁定安装命令本身很简单npm install -g anthropic-ai/claude-code但这里有个实践建议如果你是在团队里推广别用latest标签而是锁定一个具体版本。因为AI工具的迭代很快新版本可能改了交互方式或者配置格式团队里有人用新版有人用旧版沟通成本很高。锁定版本的方式npm install -g anthropic-ai/claude-code1.0.xx安装完成后验证claude --version如果提示command not found说明npm的全局bin目录不在PATH里。查一下npm config get prefix把这个路径下的bin目录加到PATH里就行。Linux/macOS加到~/.bashrc或~/.zshrcWindows加到系统环境变量。3.2 首次启动的认证流程第一次运行claude命令它会引导你做认证。这个过程是交互式的会打开浏览器让你登录。这里有个坑如果你是在远程服务器上通过SSH使用浏览器打不开。解决办法是看终端里输出的URL手动复制到本地浏览器打开完成认证后把回调的code粘贴回终端。认证信息默认存在~/.claude目录下。如果你在多台机器上用可以把认证文件同步过去省得每台都认证一遍。但注意这个文件包含敏感信息别往公开的仓库里放。3.3 配置文件的位置和结构Claude Code的配置分几层全局配置在~/.claude/settings.json项目级配置在工程根目录的.claude/settings.json还有一层是本地的.claude/settings.local.json这个通常加到.gitignore里。全局配置主要放一些个人偏好比如默认模型、主题、是否自动确认某些操作。项目级配置放跟工程相关的比如允许执行的命令白名单、需要忽略的目录。我建议一开始别急着改配置先用默认配置跑几天等你明确知道自己需要什么了再改。很多人一上来就把配置改得面目全非结果出了问题不知道是配置的锅还是工具的锅。4. 让Claude Code真正读懂嵌入式工程的关键配置4.1 项目级CLAUDE.md的写法Claude Code有个机制它会自动读取工程根目录下的CLAUDE.md文件把这个文件的内容作为上下文。这个文件是你教它理解工程的主要手段。对嵌入式工程来说CLAUDE.md里应该写什么我的经验是这几块第一工程的整体架构。用几句话说明这个固件是干什么的分哪几层各层的职责是什么。比如这是一个基于STM32F4的电机控制固件分BSP层寄存器封装、HAL层外设驱动、Control层控制算法、App层业务逻辑。第二构建方式。交叉编译工具链是什么怎么编译产物在哪。比如使用arm-none-eabi-gcc通过CMake构建build目录下生成elf和bin文件烧录用openocd配合stlink。第三代码规范。命名约定、注释风格、错误处理方式。嵌入式代码规范跟PC代码差别很大比如寄存器操作通常用宏而不是函数中断服务函数有固定命名格式这些都要写清楚。第四禁止事项。哪些目录不要动哪些文件是自动生成的哪些操作有风险。比如Drivers目录下的代码是CubeMX生成的不要手动修改。这个文件不用一次写完美用着用着发现它老犯某个错误就把对应的规则加进去。我现在的CLAUDE.md大概两百多行是几个月慢慢攒出来的。4.2 忽略规则的配置嵌入式工程里有一堆不需要AI看的文件编译产物.o、.elf、.bin、.map、IDE的工程文件.uvprojx、.ioc、第三方库的源码、文档和图片。这些如果不排除Claude Code搜索的时候会浪费大量时间在无关文件上。在.claude/settings.json里配置忽略规则{ ignorePatterns: [ build/**, Debug/**, Release/**, Drivers/CMSIS/**, Middlewares/Third_Party/**, *.elf, *.bin, *.map, *.o ] }这里有个细节CMSIS和第三方中间件虽然代码量大但有时候你确实需要它去查某个寄存器定义或者某个协议栈的实现。我的做法是默认忽略需要的时候在对话里明确告诉它去看Drivers/CMSIS下的某个文件它会临时读取。4.3 命令白名单与安全边界Claude Code可以执行shell命令这在嵌入式场景下非常有用编译、烧录、跑测试但也有风险。默认情况下它执行命令前会问你你可以配置白名单让它自动执行某些安全命令。我的白名单大概长这样{ allowedCommands: [ cmake --build build, make, arm-none-eabi-objdump, arm-none-eabi-size, ctest, git status, git diff ] }注意烧录命令openocd、st-flash我没放白名单因为烧录是物理操作万一AI理解错了要烧的固件可能把板子刷成砖。这种操作我坚持手动确认。5. 在嵌入式工作流中落地Claude Code的几个真实场景5.1 驱动开发从寄存器手册到可编译代码嵌入式驱动开发的典型流程是看芯片手册的寄存器定义写初始化序列写读写函数写中断处理然后调试。Claude Code在这个流程里能帮上忙的环节比想象中多。我最近做的一个项目是给一个SPI接口的ADC写驱动。我的做法是先把芯片手册里相关的寄存器章节截图或者复制成文本放到工程的一个docs目录下然后让Claude Code读这个文档生成寄存器定义的宏和初始化函数。它生成的代码不一定完全正确但结构是对的寄存器地址、位域定义这些机械性的工作它做得很快。生成之后我会让它对照手册检查一遍重点看位域的偏移和掩码有没有错。这一步很关键因为AI有时候会把相邻的位域搞混。检查完再编译编译过了再上板子测。5.2 单元测试用Ceedling框架自动生成测试骨架前面提到嵌入式单元测试的痛点这里展开说一下具体怎么用。假设你有一个驱动模块adc_driver.c接口在adc_driver.h里。用Ceedling的话先建好工程结构然后让Claude Code做这几件事第一读adc_driver.h理解接口。第二生成test_adc_driver.c的骨架包含setUp、tearDown和每个接口的测试函数。第三为每个接口生成正常路径和边界条件的测试用例。我实测下来一个五六个接口的驱动模块它生成的测试骨架大概覆盖了百分之七八十的场景。剩下的百分之二三十通常是硬件相关的边界条件比如超时、总线错误这些需要你根据实际硬件行为补充。生成的测试用例里mock的配置经常需要调整。Ceedling的mock机制是基于头文件自动生成的但有时候AI生成的测试会调用不存在的mock函数这时候编译会报错根据报错改就行。5.3 代码审查让它盯着你容易忽略的地方嵌入式代码审查有几个高频问题中断服务函数里调用了阻塞函数、共享变量没有加volatile、临界区没有关中断、栈使用超过预期。这些问题人眼扫代码很容易漏但可以让Claude Code专门盯。我的做法是写一个review的prompt模板每次提交前让Claude Code按这个模板过一遍改动的文件。模板大概是这样审查以下嵌入式C代码改动重点检查1中断上下文中的函数调用是否安全2共享变量的volatile修饰3临界区保护4数组越界风险5未初始化的指针6整数溢出。对每个问题给出文件、行号和修改建议。这个模板不是万能的但它能抓住大部分低级错误。我用了几个月确实帮我逮到过几次中断里调printf这种问题。5.4 构建脚本维护CMake和Makefile的救星嵌入式工程的构建脚本往往是最乱的部分因为经常是几代人改下来的CMakeLists里堆了一堆条件判断和遗留配置。Claude Code读这种脚本的能力不错你可以让它解释某段配置是干什么的或者让它帮你加一个新的源文件目录。我遇到过一个典型场景工程要从STM32F4迁移到STM32H7工具链的浮点ABI从softfp变成hard链接脚本要改启动文件要换编译选项要调。这种迁移工作繁琐但规律性强我让Claude Code先分析现有配置列出所有需要改的点然后逐个改。它列出的清单比我手动找的全省了不少时间。6. 那些官方文档不会告诉你的坑6.1 中文路径和空格路径的灾难这个坑我踩过两次。第一次是工程放在D:\我的项目\固件下面Claude Code读取文件时路径解析出错。第二次是路径里有空格D:\my project\firmware同样出问题。解决办法很简单工程路径全用英文不要有空格不要有中文。如果实在要用中文目录名用WSL挂载的时候注意转义。这个坑的本质是CLI工具对路径的处理依赖shell而shell对特殊字符的处理规则很复杂AI生成的命令不一定每次都转义正确。6.2 大文件读取的截断问题嵌入式工程里有些文件特别大比如某些芯片的头文件几万行。Claude Code读取这种文件时可能会截断只读前面一部分。如果你让它基于这个文件做分析它可能漏掉后面的定义。应对办法是需要它看大文件时明确告诉它看哪一段或者用grep先定位行号再让它读指定行范围。比如读stm32h7xx.h的第3000到3500行这样它就不会盲目读整个文件。6.3 交叉编译环境的PATH继承问题如果你在WSL里跑Claude Code但工具链装在Windows侧PATH是继承不过来的。反过来也一样。这个问题的表现是Claude Code执行编译命令时报arm-none-eabi-gcc: command not found。解决办法是在启动Claude Code之前先在当前shell里确认工具链可用which arm-none-eabi-gcc如果找不到先把工具链的bin目录加到PATH里再启动Claude Code。因为Claude Code继承的是启动时的环境变量启动后再改PATH它看不到。6.4 模型对汇编和链接脚本的理解有限Claude Code对C代码的理解很好但对汇编和链接脚本的理解明显弱一些。启动文件里的汇编、链接脚本里的内存布局它经常给出似是而非的建议。我的做法是汇编和链接脚本的改动只让它做机械性的替换比如改个地址、改个段名不做逻辑性的修改。逻辑性的改动还是自己来或者至少自己完整review一遍。6.5 上下文窗口与长对话的衰减Claude Code有上下文窗口限制长对话到后面它会忘记前面的内容。在嵌入式场景下这意味着如果你在一个对话里既聊驱动又聊测试又聊构建到后面它可能把不同模块的信息搞混。我的习惯是一个任务一个对话。写完驱动就结束对话开新对话写测试。这样每个对话的上下文都是干净的它的表现更稳定。7. 把Claude Code嵌进日常开发节奏的几点体会用到现在我最大的感受是Claude Code不是替代你写代码而是替代你做那些机械但需要理解上下文的工作。嵌入式开发里这种工作特别多——查寄存器、写测试骨架、改构建脚本、review代码这些事你都会做但做起来费时间而且容易因为疲劳出错。我现在的日常节奏大概是早上到工位先让Claude Code过一遍昨天提交的代码看有没有明显问题然后开始当天的开发任务写新模块的时候让它生成骨架我填核心逻辑下午跑测试让它根据失败的用例分析可能的原因下班前让它整理一下当天的改动生成commit message。这个节奏不是一天形成的是用了两三个月慢慢磨出来的。中间也走过弯路比如一开始什么都让它做结果它生成的代码质量参差不齐review的时间比我自己写还长。后来想明白了它的定位是高级助手不是代笔。你给它越明确的任务、越充分的上下文它的产出质量越高。还有一点别指望它一次就对。嵌入式代码的正确性最终要靠硬件验证AI生成的代码只是起点不是终点。编译过了不代表逻辑对逻辑对了不代表时序对时序对了不代表边界条件处理对了。这个链条上的每一环都得你自己把关。最后分享一个我最近发现的小技巧让Claude Code在生成代码的时候顺便生成对应的单元测试。这样你拿到代码的同时就有了测试骨架改代码的时候心里有底。这个习惯养成之后我的代码返工率明显下降了。
返回列表