嵌入式软件工程师-Claude Code 使用技巧
压缩对话时,始终保留已修改文件的完整列表。创建"""嵌入式开发 MCP Server - 串口日志监控功能:读取串口日志、分析异常、解析协议数据"""import sys"""读取串口数据并返回最近 N 行日志"""lines = []for _ in range(100): # 读取最近 100 行if line:"""分析串口日志文件,提取错误和异常"""嵌入式开发 MCP Server -
嵌入式软件Claude Code 使用技巧
目录
- 基础命令与快捷键
- 高效提示词技巧
- 核心功能详解
- IDE 集成
- 工作流优化
- 上下文与记忆管理
- 权限与安全
- 高级技巧与隐藏功能
- 插件与工具集成
- 多人协同开发
- 多 Agent 协同开发
- 高级命令与隐藏技巧速查
- 常见问题与排错
1. 基础命令与快捷键
启动方式
claude # 启动交互式会话
claude -p "提示内容" # 非交互式单次运行
claude --continue # 恢复最近一次对话
claude --resume # 从历史对话中选择恢复
claude --project /path/to/project # 指定项目目录启动
# 嵌入式开发常用启动方式
claude --project ~/stm32-firmware # 打开 STM32 固件项目
claude -p "分析当前工程的链接脚本 ld 文件" # 快速分析链接脚本
常用 CLI 参数
| 参数 | 说明 |
|---|---|
--output-format json |
以 JSON 格式输出,适合程序解析 |
--output-format stream-json |
流式 JSON 输出 |
--permission-mode auto |
自动权限模式,减少确认提示 |
--allowedTools |
限制可用工具范围 |
--verbose |
开启调试模式,显示详细信息 |
嵌入式开发常用参数示例:
# 自动模式编译固件,减少确认弹窗
claude -p "编译并分析编译警告" --permission-mode auto
# 限制工具范围,仅做代码阅读和分析(不修改文件)
claude -p "分析 drivers/ 目录下的外设驱动架构" --allowedTools Read,Grep,Glob
# JSON 输出用于脚本解析(如 CI/CD 中自动检查代码规范)
claude -p "检查所有 C 文件是否符合 MISRA-C 规范" --output-format json
交互模式快捷键
| 快捷键 | 功能 |
|---|---|
Esc |
中途停止当前操作(保留上下文) |
Esc + Esc |
打开回退菜单,恢复之前状态 |
Ctrl+C |
取消当前操作 |
Ctrl+G |
在编辑器中打开当前计划(计划模式) |
Shift+Tab |
切换权限模式 |
@文件名 |
直接引用文件,Claude 会先读取再回答 |
嵌入式开发常用引用示例:
@stm32f407.ld # 引用链接脚本分析内存布局
@drivers/spi/spi_driver.c # 引用 SPI 驱动源文件
@Inc/stm32f4xx_hal_conf.h # 引用 HAL 配置文件
@Makefile # 引用构建脚本
@startup_stm32f407xx.s # 引用启动文件分析中断向量表
常用斜杠命令
| 命令 | 说明 |
|---|---|
/clear |
重置上下文,适用于切换不相关任务 |
/compact <指令> |
手动压缩对话历史 |
/init |
基于代码库生成初始 CLAUDE.md 文件 |
/rewind |
打开检查点回退菜单 |
/rename "名称" |
给当前会话命名 |
/btw <问题> |
问一个旁路问题,不进入历史 |
/permissions |
配置权限规则 |
/sandbox |
设置沙箱规则 |
/hooks |
查看已配置的钩子 |
/plugin |
浏览和安装插件 |
/fast |
切换快速模式(同一模型,输出更快) |
2. 高效提示词技巧
核心原则:具体、精确、可验证
差的提示词:
修一下 bug
好的提示词:
修复 src/auth/session.ts 中的 token 过期 bug,
用户反馈在会话超时后登录失败。
测试用例:超时 30 分钟后再次请求应返回 401。
嵌入式开发 - 差的提示词:
帮我看看串口为什么不通
嵌入式开发 - 好的提示词:
分析 @drivers/uart/uart_driver.c 中的 UART3 初始化配置。
现象:使用 STM32F407 的 USART3 发送数据时,
接收端只收到乱码。波特率设置为 115200。
请检查时钟配置、GPIO 复用、波特率寄存器设置是否一致。
当前使用 HSE 8MHz 外部晶振,PLL 倍频到 168MHz。
推荐的提示词模式
模式一:任务描述公式
[做什么] + [在哪里] + [怎么做] + [如何验证]
示例:
为 foo.py 编写测试,覆盖用户未登录的边界情况。
参考 tests/auth/ 目录下的现有测试模式。实现后运行测试。
嵌入式开发示例:
为 I2C 驱动模块 drivers/i2c/i2c_master.c 编写单元测试框架,
使用 CMock/Unity 测试框架,覆盖以下场景:
1. 总线忙超时处理
2. NACK 应答错误恢复
3. 多字节连续读写的时序正确性
参考 tests/test_spi_driver.c 的测试模式。测试通过标准:make test 无失败用例。
模式二:代码参考模式
先看 @src/middleware/auth.ts 是如何处理 token 验证的,
然后在新的 session manager 中实现类似逻辑。
嵌入式开发示例:
先看 @drivers/spi/spi_driver.c 中 SPI 的 DMA 收发实现模式,
包括中断回调、错误处理和超时机制,
然后在新的 I2S 音频驱动中实现类似的 DMA 双缓冲传输逻辑。
参考 HAL 库中 HAL_I2S_Transmit_DMA 的用法。
模式三:调查分析模式
为什么 ExecutionFactory 的 API 设计这么奇怪?
查看它的 git 历史,总结其演进过程,重点关注破坏性变更。
嵌入式开发示例:
为什么 FreeRTOS 任务调度会在 ADC 采样时出现偶发性的任务饿死?
查看 tasks.c 和 timers.c 的 git 提交历史,
重点分析最近几次关于 tick 中断优先级和 SysTick 配置的变更。
同时检查当前的中断优先级分组设置是否合理。
模式四:需求收集模式
使用 AskUserQuestion 工具来采访我,了解需求细节。
询问技术实现、UI/UX、边界情况、权衡取舍等方面。
收集完所有信息后,将规格写入 SPEC.md。
嵌入式开发示例:
使用 AskUserQuestion 工具来采访我,了解新外设驱动的需求细节。
询问以下方面:
1. 目标 MCU 型号和硬件资源(定时器、DMA 通道、GPIO 引脚)
2. 通信协议时序要求(时钟频率、CS 片选策略)
3. 中断 vs 轮询的选择偏好
4. 功耗要求和低功耗模式兼容性
5. RTOS 是否使用,线程安全要求
收集完所有信息后,将驱动设计规格写入 DRIVER_SPEC.md。
提示词注意事项
| 应该做 | 不应该做 |
|---|---|
| 指定具体文件路径 | 使用模糊描述如"那个文件" |
| 提供验证标准 | 过度指定(太多上下文会淹没指令) |
| 指定遵循的模式示例 | 一次塞太多不相关的任务 |
任务之间使用 /clear |
在失败的修正上反复重试超过 2 次 |
嵌入式开发提示词注意事项:
| 应该做 | 不应该做 |
|---|---|
| 指定 MCU 型号和时钟配置 | 只说"芯片上跑不起来" |
| 提供寄存器地址或外设实例编号 | 假设 Claude 知道你的硬件原理图 |
| 说明编译工具链(arm-none-eabi-gcc) | 忽略编译器版本差异 |
| 提供示波器/逻辑分析仪抓到的波形描述 | 只说"波形不对" |
| 说明是否使用 RTOS 及其版本 | 混淆裸机和 RTOS 的编程模式 |
3. 核心功能详解
CLAUDE.md —— 项目指令文件
CLAUDE.md 是 Claude Code 的"项目说明书",告诉 Claude 你的项目约定。
放置位置(按优先级从低到高):
~/.claude/CLAUDE.md # 全局:所有会话生效
./CLAUDE.md # 项目级(提交到 git)
./CLAUDE.local.md # 个人笔记(加入 .gitignore)
子目录/CLAUDE.md # 按需加载
应该包含的内容:
- Claude 无法猜到的自定义 Bash 命令
- 与默认不同的代码风格规则
- 测试指令和首选测试运行器
- Git 工作流约定(分支命名、PR 规范)
- 项目特有的架构决策
- 开发环境特殊配置(必需的环境变量等)
嵌入式项目还应包含:
- 交叉编译工具链路径和版本
- 烧录/下载命令(如 OpenOCD、J-Link、ST-Link)
- 调试命令(如 GDB 启动方式)
- 目标 MCU 型号、内核架构(Cortex-M3/M4/M7 等)
- 是否使用 RTOS(FreeRTOS/RT-Thread/UCOS 等)及版本
- 外设库/HAL 库版本(STM32 HAL、NXP SDK 等)
- 内存限制(Flash/RAM 大小)和特殊约束
- 构建系统(Makefile/CMake/Keil/IAR)的构建命令
不应该包含的内容:
- Claude 能通过阅读代码了解的信息
- 标准语言惯例
- 频繁变化的信息
- "写干净的代码"这类不言自明的建议
示例 CLAUDE.md:
# 项目约定
## 构建
- 使用 `pnpm build` 构建项目
- 使用 `pnpm test` 运行测试
## 代码风格
- 使用 ESM 模块(import/export),不用 CommonJS
- 组件使用 PascalCase 命名
- API 路由使用 kebab-case
## Git 工作流
- 分支命名:feat/xxx, fix/xxx, chore/xxx
- PR 必须经过 code review
## 参考
- API 文档:@docs/api.md
- 数据库模式:@docs/schema.md
嵌入式项目示例 CLAUDE.md:
# 嵌入式项目约定
## 目标平台
- MCU: STM32F407VET6, Cortex-M4F, 168MHz
- Flash: 512KB, RAM: 192KB
- 外部晶振: HSE 8MHz
## 构建系统
- 工具链: arm-none-eabi-gcc 12.2 (下载链接见 docs/setup.md)
- 构建命令: `make all`(Makefile 项目)
- 清理: `make clean`
- 编译输出: build/firmware.elf / .hex / .bin
## 烧录与调试
- 烧录: `make flash`(使用 ST-Link V2 + OpenOCD)
- 调试: `make debug`(启动 arm-none-eabi-gdb + OpenOCD)
- 串口日志: `make monitor`(minicom, 115200 8N1)
## RTOS
- FreeRTOS V10.5.1,使用 heap_4 内存管理方案
- 任务优先级范围:0(最低)- 5(最高),idle 任务为 0
- 中断优先级分组:NVIC_PriorityGroup_4(4 位抢占优先级)
## 代码风格
- 遵循 MISRA-C:2012 指南(强制规则)
- 函数命名:模块_动作_对象,如 `UART_SendBuffer()`
- 变量命名:类型前缀 + 名称,如 `uint32_t uwTick`, `uint8_t ucData`
- 全局变量加 g_ 前缀,如 `g_ulSystemClock`
- 头文件使用 `#ifndef` 保护
- 寄存器操作必须通过 HAL 库或 BSP 层,禁止直接操作寄存器
## 测试
- PC 端单元测试:`make unittest`(Unity + CMock 框架)
- 硬件在环测试:见 tests/hil/ 目录
- 静态分析:`make cppcheck` 和 `make clang-tidy`
## 架构分层
- App/ 应用层(业务逻辑)
- Middleware/ 中间件(协议栈、文件系统等)
- Drivers/ 驱动层(BSP + HAL 封装)
- CMSIS/ 系统层(启动文件、系统初始化)
Hooks(钩子)—— 自动化脚本
Hooks 在特定工作流节点自动执行脚本,保证每次都运行。
支持的钩子事件:
| 事件 | 触发时机 |
|---|---|
pre_command |
Claude 执行命令之前 |
post_command |
Claude 执行命令之后 |
pre_edit |
Claude 编辑文件之前 |
post_edit |
Claude 编辑文件之后 |
pre_mcp_tool |
使用 MCP 工具之前 |
post_mcp_tool |
使用 MCP 工具之后 |
配置示例(.claude/settings.json):
{
"hooks": {
"post_edit": {
"command": "eslint --fix {file}",
"run": "per_file"
},
"pre_command": {
"command": "block_dangerous_commands.sh",
"run": "once_per_session"
}
}
}
嵌入式开发 Hooks 示例:
{
"hooks": {
"post_edit": {
"command": "clang-format -i -style=file {file}",
"run": "per_file"
},
"pre_command": {
"command": "check_not_flash.sh",
"run": "once_per_session"
}
}
}
说明:
post_edit:每次编辑 C/H 文件后自动运行clang-format格式化代码pre_command:阻止 Claude 意外执行make flash等烧录命令(防止误操作烧录到硬件)
Skills(技能)—— 可复用的工作流
创建自定义技能:
在 .claude/skills/fix-issue/SKILL.md 中:
---
name: fix-issue
description: 修复 GitHub issue
disable-model-invocation: true
---
分析和修复 GitHub issue:$ARGUMENTS
1. 使用 `gh issue view` 获取 issue 详情
2. 理解问题
3. 搜索代码库
4. 实现修改
5. 编写并运行测试
6. 提交并创建 PR
使用方式: /fix-issue 1234
嵌入式开发自定义技能示例:
在 .claude/skills/analyze-hardfault/SKILL.md 中:
---
name: analyze-hardfault
description: 分析 HardFault 崩溃堆栈
---
分析 HardFault 崩溃原因:$ARGUMENTS
1. 读取 HardFault_Handler 中保存的寄存器(PC、LR、PSR、CFSR、HFSR、MMFAR、BFAR)
2. 根据崩溃的 PC 地址,在 .map 文件中定位崩溃函数
3. 分析 CFSR 寄存器各位,判断具体故障类型:
- IMPRECISERR / PRECISERR:总线错误
- INVSTATE / INVPC:用法错误(无效状态/无效PC加载)
- DACCVIOL:内存访问权限错误
4. 结合反汇编(arm-none-eabi-objdump)分析崩溃点指令
5. 给出可能的修复建议
使用方式:/analyze-hardfault PC=0x08002A3C LR=0x08001F51 CFSR=0x00000200
在 .claude/skills/gen-peripheral/SKILL.md 中:
---
name: gen-peripheral
description: 根据配置生成外设初始化代码
---
根据以下配置生成外设初始化代码:$ARGUMENTS
1. 读取 @Inc/stm32f4xx_hal_conf.h 确认已启用的 HAL 模块
2. 参考现有驱动(如 @Drivers/uart_driver.c)的代码风格
3. 生成 GPIO 配置、时钟使能、外设初始化、中断配置代码
4. 生成对应的头文件,包含 API 声明和文档注释
5. 确保代码符合 MISRA-C 规范
全面代码审查技能完整创建指南
以下是创建一个专业级嵌入式全面代码审查技能的完整步骤,包含目录结构、配置文件、审查清单和实际使用示例。
第一步:创建目录结构
# 在项目根目录下执行
mkdir -p .claude/skills/full-review
第二步:创建技能定义文件
创建 .claude/skills/full-review/SKILL.md:
---
name: full-review
description: 嵌入式代码全面审查(内存安全、并发安全、代码规范、硬件正确性)
---
对指定文件或目录进行全面代码审查:$ARGUMENTS
## 执行步骤
1. 确认审查范围
- 如果参数是文件路径,审查该文件
- 如果参数是目录路径,列出目录下所有 .c/.h 文件,逐个审查
- 如果参数是空,审查当前 git diff 中变更的文件
2. 读取项目约定
- 读取 @CLAUDE.md 了解代码风格和架构规则
- 读取 @.claude/rules/ 目录下的规则文件(如有)
3. 按以下六大维度逐一审查,每个维度独立输出一个小节
---
## 审查维度一:内存安全
### 1.1 数组越界检查
- [ ] 所有数组下标访问是否有边界检查(for 循环的上界是否正确)
- [ ] 接收缓冲区写入前是否校验了剩余空间
- [ ] DMA 传输长度与目标缓冲区大小是否匹配
- [ ] 字符串操作(strcpy/strcat/sprintf)是否会越界,是否改用 strncpy/snprintf
- [ ] 结构体数组访问是否检查了索引范围
- [ ] FIFO/环形缓冲区的读写指针回绕是否正确
### 1.2 指针安全检查
- [ ] 所有指针使用前是否已初始化(非 NULL)
- [ ] 函数参数中的指针是否做了 NULL 检查(公开 API 必须)
- [ ] free/vPortFree 后指针是否立即置 NULL(防止 use-after-free)
- [ ] 函数返回指针时,是否指向了有效的内存区域(非局部变量地址)
- [ ] 函数指针调用前是否检查了指针有效性
### 1.3 栈空间评估
- [ ] 局部数组是否过大(超过 256 字节建议改为 static 或动态分配)
- [ ] 函数调用深度是否可控(建议不超过 8 层)
- [ ] 递归调用是否有明确的终止条件
- [ ] 是否在 FreeRTOS 任务中调用了大栈消耗函数(如 printf、sprintf)
- [ ] 估算函数最大栈消耗 = 局部变量 + 调用链中的最大栈帧
### 1.4 内存泄漏检查
- [ ] 所有 malloc/pvPortMalloc 是否有对应的 free/vPortFree
- [ ] 错误处理分支(goto error 路径)是否遗漏了已分配内存的释放
- [ ] 提前 return 的路径是否释放了已分配的资源
- [ ] 是否存在重复释放(double free)的风险
---
## 审查维度二:并发与中断安全
### 2.1 中断安全
- [ ] ISR 中是否调用了阻塞函数(HAL_Delay、printf、xSemaphoreTake → 违规)
- [ ] ISR 中是否使用了非可重入函数(strtok、rand、static 局部变量函数)
- [ ] ISR 中调用的 FreeRTOS API 是否使用了 FromISR 版本
- [ ] ISR 中的操作是否足够短(建议不超过 10us 或 50 条指令)
- [ ] 中断标志清除是否在处理完成后、退出前执行
- [ ] 嵌套中断是否安全(更高优先级中断能否打断当前 ISR)
### 2.2 中断优先级
- [ ] ISR 优先级数值是否 >= configMAX_SYSCALL_INTERRUPT_PRIORITY(FreeRTOS 要求)
- [ ] 多个中断之间的优先级关系是否合理:
- 通信接收中断(UART/SPI/CAN)优先级 > 定时器中断
- 看门狗喂狗中断优先级应最高
- ADC 采样完成中断优先级 > 数据处理任务优先级
- [ ] 是否参考了 @docs/interrupt_priority.md 的分配表
### 2.3 互斥与共享资源
- [ ] ISR 与主循环/任务之间共享的变量是否使用了 volatile
- [ ] 多任务访问的全局变量/外设寄存器是否有互斥保护
- [ ] taskENTER_CRITICAL / taskEXIT_CRITICAL 是否成对出现
- [ ] xSemaphoreTake / xSemaphoreGive 是否成对出现
- [ ] 多个互斥锁的获取顺序是否一致(防止死锁:总是按 A→B→C 顺序获取)
- [ ] 临界区内是否做了最少操作(不做耗时操作、不调用阻塞 API)
### 2.4 竞态条件
- [ ] 标志位/状态机的状态切换是否原子(不会被中断打断导致状态不一致)
- [ ] 多字节共享数据的读写是否在临界区内完成
- [ ] DMA 双缓冲切换时是否有数据撕裂风险
---
## 审查维度三:代码规范与可读性
### 3.1 命名规范
- [ ] 函数名是否符合项目命名规则(如 模块_动作_对象:UART_SendBuffer)
- [ ] 变量名是否有类型前缀(如 uwCount、ucBuffer、pxHandle)
- [ ] 全局变量是否有 g_ 前缀
- [ ] 宏定义是否全大写+下划线(如 #define MAX_BUFFER_SIZE 256)
- [ ] 枚举值是否有模块前缀(如 ADC_CHANNEL_0, ADC_CHANNEL_1)
- [ ] 命名是否自描述(避免 a, b, tmp, data, ret 这类无意义命名)
### 3.2 MISRA-C 合规
- [ ] 条件表达式中是否使用了赋值(if (x = 0) → 违规)
- [ ] switch 语句是否每个 case 都有 break,是否有 default
- [ ] 是否有隐式类型转换(特别是有符号/无符号混用)
- [ ] 指针算术是否在数组边界内
- [ ] 是否使用了未限制大小的 goto(只允许向前跳转用于错误处理)
- [ ] 函数是否只有一个出口点(或使用 goto error 集中处理)
- [ ] 是否有未使用的参数或变量
- [ ] #include 中是否使用了 <> 包含项目内部文件(应使用 "")
### 3.3 魔术数字
- [ ] 代码中是否直接使用了数字常量(如 if (reg & 0x01))
- [ ] 是否应替换为有意义的宏或枚举
- [ ] 正确示例:if (reg & USART_SR_RXNE_FLAG) 而非 if (reg & 0x40)
### 3.4 代码结构
- [ ] 函数长度是否合理(建议不超过 50 行,超过则拆分为子函数)
- [ ] 嵌套深度是否超过 3 层 if(超过建议用 guard clause 提前 return)
- [ ] 函数职责是否单一(一个函数只做一件事)
- [ ] 重复代码是否提取为公共函数
### 3.5 注释质量
- [ ] 公开函数是否有头注释(功能描述、参数说明、返回值、注意事项)
- [ ] 关键算法/时序/硬件操作是否有行内注释
- [ ] 注释是否与代码一致(修改代码时是否同步更新了注释)
- [ ] 是否有过多废话注释(如 i++; // i 加 1)
- [ ] 硬件相关操作是否标注了数据手册章节号
- [ ] TODO/FIXME/HACK 是否标注了日期、作者和原因
---
## 审查维度四:C 语言标准与类型安全
### 4.1 类型使用
- [ ] 是否统一使用 stdint.h 类型(uint8_t/uint32_t 而非 int/unsigned)
- [ ] 是否有隐式类型转换导致的精度丢失(如 uint32_t → uint8_t)
- [ ] 有符号/无符号混用是否会导致逻辑错误
- [ ] 枚举是否用于定义有限状态和错误码(而非散落的 #define)
### 4.2 关键字使用
- [ ] static 是否正确使用(限制作用域到文件内、保持函数间状态)
- [ ] const 是否正确使用(不修改的参数、只读的指针)
- [ ] volatile 是否在硬件寄存器和 ISR 共享变量上使用
- [ ] extern 是否仅在头文件中声明,定义在 .c 文件中
### 4.3 未定义行为
- [ ] 移位操作是否有未定义行为(对有符号数左移、移位量 >= 位宽)
- [ ] 指针是否做了违反严格别名规则(strict aliasing)的类型转换
- [ ] 除法是否有除零风险
- [ ] 结构体是否有适当的对齐和打包属性(__attribute__((packed)) 用于协议帧)
---
## 审查维度五:错误处理
### 5.1 返回值检查
- [ ] HAL 函数返回值是否全部检查(HAL_OK / HAL_ERROR / HAL_TIMEOUT)
- [ ] 自定义函数的错误返回值是否被调用者检查
- [ ] 是否存在忽略返回值的情况(如 (void)HAL_UART_Transmit())
### 5.2 错误恢复
- [ ] 超时处理后是否有恢复机制(重试、复位外设、上报错误)
- [ ] 总线错误(I2C NACK、SPI CRC 错误、CAN Bus-Off)是否有恢复流程
- [ ] DMA 传输错误是否有重新初始化的流程
- [ ] 外设初始化失败是否有降级方案或系统告警
### 5.3 防御性编程
- [ ] 公开 API 的参数是否有有效性检查(NULL 指针、越界索引)
- [ ] 状态机是否有非法状态的防护(default 分支)
- [ ] 数组索引是否有上限检查
- [ ] 是否有断言(assert)用于开发阶段捕获不可达条件
---
## 审查维度六:硬件与外设正确性
### 6.1 外设配置
- [ ] GPIO 引脚复用(AF)是否与原理图一致
- [ ] 时钟使能是否遗漏(RCC 时钟必须在访问寄存器前开启)
- [ ] 外设时钟频率是否在规格范围内(如 SPI 时钟不超过外设最大频率)
- [ ] 模拟外设的参考电压配置是否正确(ADC/DAC VREF)
### 6.2 DMA 配置
- [ ] DMA 通道/流是否正确(对应具体外设请求)
- [ ] 源地址、目标地址、传输方向、数据宽度是否正确
- [ ] 循环模式 vs 正常模式的选择是否正确
- [ ] 缓冲区是否对齐到缓存行大小(D-Cache 场景需 32 字节对齐)
- [ ] DMA 传输完成和传输错误中断是否都处理了
### 6.3 时序与功耗
- [ ] 看门狗喂狗间隔是否小于看门狗超时时间(留足够余量)
- [ ] 低功耗模式退出后外设是否需要重新初始化
- [ ] 通信协议的时序要求是否满足(setup time / hold time)
- [ ] ADC 采样时间是否足够(根据源阻抗计算)
---
## 输出格式
### 每条审查意见必须包含:
严重程度 | 文件名:行号 | 规则编号 | 问题描述 | 修改建议
### 严重程度定义:
- [BLOCK] 必须修改后才能合并(安全/功能 bug、数据损坏风险)
- [WARN] 强烈建议修改(潜在 bug、性能问题、可维护性差)
- [SUGGEST] 建议修改(代码风格、命名优化、注释补充)
### 最终输出汇总报告:
代码审查报告
审查范围
- 文件列表和总行数
问题统计
| 维度 | BLOCK | WARN | SUGGEST | 合计 |
|---|---|---|---|---|
| 内存安全 | ||||
| 并发与中断安全 | ||||
| 代码规范与可读性 | ||||
| C 标准与类型安全 | ||||
| 错误处理 | ||||
| 硬件与外设正确性 | ||||
| 合计 |
问题详情
(按严重程度从高到低排列)
总体评价
- 代码质量等级:优秀 / 良好 / 需改进 / 不合格
- 主要风险点
- 改进建议(Top 3 优先级)
第三步:在 CLAUDE.md 中声明技能
在项目根目录的 CLAUDE.md 中添加:
## 可用技能
- `/full-review <文件或目录>` — 全面代码审查(六大维度、100+ 检查项)
- `/analyze-hardfault <寄存器信息>` — HardFault 崩溃分析
- `/gen-peripheral <配置描述>` — 外设初始化代码生成
第四步:验证技能是否可用
# 启动 Claude Code,输入:
/full-review @Drivers/can/can_driver.c
# 如果技能配置正确,Claude 会自动展开审查流程
第五步:使用示例
# 审查单个驱动文件
/full-review @Drivers/spi/spi_master.c
# 审查整个目录
/full-review Drivers/ADC/
# 审查当前 git 变更
/full-review
# 审查中间件模块
/full-review @Middleware/modbus/modbus_slave.c
审查报告输出示例:
# 代码审查报告
## 审查范围
- Drivers/spi/spi_master.c (312 行)
- Drivers/spi/spi_master.h (68 行)
## 问题统计
| 维度 | BLOCK | WARN | SUGGEST | 合计 |
|------|-------|------|---------|------|
| 内存安全 | 1 | 2 | 0 | 3 |
| 并发与中断安全 | 1 | 1 | 0 | 2 |
| 代码规范与可读性 | 0 | 1 | 3 | 4 |
| C 标准与类型安全 | 0 | 0 | 1 | 1 |
| 错误处理 | 1 | 0 | 0 | 1 |
| 硬件与外设正确性 | 0 | 1 | 0 | 1 |
| **合计** | **3** | **5** | **4** | **12** |
## 问题详情
### [BLOCK] spi_master.c:145 | 内存安全-数组越界
**问题:** SPI_ReceiveBuffer 中 DMA 传输长度使用参数 length,
未校验 length 是否超过 g_ucRxBuf 的大小(256 字节)。
**修改建议:** 添加参数校验:
```c
if (length > SPI_MAX_BUFFER_SIZE) {
return SPI_ERR_BUFFER_OVERFLOW;
}
[BLOCK] spi_master.c:198 | 并发安全-临界区缺失
问题: g_ucTransferBusy 是在 SPI ISR 中清除、在此函数中检查的共享变量,
未使用 volatile 修饰且未在临界区内访问。
修改建议: 添加 volatile 并使用临界区:
volatile uint8_t g_ucTransferBusy;
// 读取时:
taskENTER_CRITICAL();
uint8_t busy = g_ucTransferBusy;
taskEXIT_CRITICAL();
[BLOCK] spi_master.c:267 | 错误处理-返回值未检查
问题: HAL_SPI_Transmit_DMA 的返回值被忽略(强制转换为 void)。
如果 DMA 启动失败,调用者不会知道。
修改建议: 检查并返回错误:
HAL_StatusTypeDef status = HAL_SPI_Transmit_DMA(&g_hSpi, pData, length);
if (status != HAL_OK) {
return SPI_ERR_DMA_START_FAILED;
}
[WARN] spi_master.c:89 | 代码规范-魔术数字
问题: SPI1->CR1 |= 0x0380; 直接使用十六进制设置波特率分频。
修改建议: 替换为宏定义:
#define SPI_BAUDRATE_PRESCALER_256 (0x07 << 3)
SPI1->CR1 |= SPI_BAUDRATE_PRESCALER_256;
…
总体评价
- 代码质量等级:需改进
- 主要风险点:DMA 缓冲区无边界检查、共享变量缺少同步保护
- Top 3 优先改进:
- 为所有 DMA 传输添加缓冲区大小校验(安全关键)
- 为 ISR 共享变量添加 volatile 和临界区保护
- 统一 HAL 函数返回值检查
### MCP Servers —— 外部工具集成
连接外部工具到 Claude Code:
```bash
claude mcp add notion # 集成 Notion
claude mcp add figma # 集成 Figma
claude mcp add database # 连接数据库
配置示例(.claude/settings.json):
{
"mcpServers": {
"notion": {
"command": "npx",
"args": ["-y", "@notionhq/mcp-server"]
}
}
}
常见用途:
- 连接 Notion 做 issue 跟踪
- 从 Figma 拉取设计稿
- 直接查询数据库
- 连接监控系统
- 跨服务自动化工作流
嵌入式开发 MCP 扩展思路:
- 连接 JTAG 调试服务器,让 Claude 直接读取芯片寄存器
- 集成串口日志工具,自动分析运行时日志
- 连接 Jenkins/GitLab CI,获取编译结果和固件大小报告
- 集成芯片数据手册搜索工具,快速查阅寄存器定义
- 连接 Jira/Redmine 做 bug 跟踪和任务管理
Subagents(子代理)—— 专业助手
在 .claude/agents/security-reviewer.md 中定义:
---
name: security-reviewer
description: 审查代码安全漏洞
tools: Read, Grep, Glob, Bash
model: opus
---
你是一位高级安全工程师。审查代码中的:
- 注入漏洞(SQL、XSS、命令注入)
- 认证和授权缺陷
- 代码中的密钥或凭据
- 不安全的数据处理
提供具体的行号引用和修复建议。
使用方式:
使用子代理审查这段代码的安全问题。
嵌入式开发 Subagent 示例:
在 .claude/agents/memory-analyzer.md 中:
---
name: memory-analyzer
description: 分析固件内存使用和栈溢出风险
tools: Read, Grep, Glob, Bash
---
你是一位嵌入式系统内存分析专家。分析项目的内存使用情况:
- 检查 .ld 链接脚本中的内存分区配置
- 分析 .map 文件中各模块的 Flash 和 RAM 占用
- 检查 FreeRTOS 任务栈大小是否足够(考虑最坏情况调用深度)
- 检查全局数组和缓冲区大小是否合理
- 计算剩余 RAM 空间,评估是否会触发 stack/heap 碰撞
- 识别可能的内存泄漏(malloc 无 free、pvPortMalloc 无 vPortFree)
提供具体的优化建议和代码行号引用。
在 .claude/agents/isr-reviewer.md 中:
---
name: isr-reviewer
description: 审查中断服务程序的正确性
tools: Read, Grep, Glob
---
你是一位嵌入式实时系统专家。审查中断服务程序(ISR):
- ISR 中是否调用了阻塞函数(如 HAL_Delay、printf、mutex)
- ISR 中是否使用了非可重入函数
- 中断优先级是否设置正确(FreeRTOS 系统调用需 >= configMAX_SYSCALL_INTERRUPT_PRIORITY)
- 是否在中断中进行了过多的数据处理(应使用 DMA 或延迟到任务中处理)
- 中断标志是否正确清除(注意清除顺序,避免重复进入)
- 共享变量是否使用了 volatile 关键字
- DMA 传输完成中断和错误中断是否都处理了
提供具体的行号引用和修复建议。
4. IDE 集成
VS Code
- 安装 Claude Code 扩展
- 配置 API 凭据
- 在集成终端中无缝使用 Claude
- 利用代码智能插件实现精确的符号导航
- 编辑后自动检测错误
JetBrains 系列
支持:IntelliJ IDEA、PyCharm、WebStorm、PhpStorm、CLion、RubyMine、GoLand、Rider
- 与 JetBrains 重构工具集成
- 原生测试运行器集成
- 项目结构感知
嵌入式开发推荐:CLion
- CLion 原生支持 C/C++ 项目,与 CMake/Makefile 深度集成
- 支持嵌入式工具链配置(交叉编译)
- 内置 OpenOCD/J-Link 调试集成
- 配合 Claude Code 可实现"描述需求 -> 生成驱动代码 -> 编译 -> 烧录"的完整工作流
Claude in Chrome 扩展
- 在浏览器中打开新标签页测试 UI
- 自动测试 UI 修改
- 迭代直到代码工作正常
- 非常适合前端开发
5. 工作流优化
四阶段工作流
第一阶段:探索(计划模式)
阅读 /src/auth 目录,了解我们如何处理会话。
同时看看环境变量管理中关于密钥的部分。
嵌入式探索示例:
阅读 @Core/Src/main.c 和 @Core/Src/stm32f4xx_it.c,
了解当前的中断配置和优先级分配情况。
同时看看 FreeRTOS 任务创建部分(@Core/Src/freertos.c),
列出所有任务及其栈大小和优先级。
另外检查 @Drivers/ 目录下有哪些外设驱动已实现。
第二阶段:规划
我想添加 Google OAuth。需要修改哪些文件?
会话流程是什么?创建一个计划。
- 按
Ctrl+G在编辑器中打开计划 - 在 Claude 执行前直接编辑计划
嵌入式规划示例:
我想添加一路 CAN 总线通信功能,使用 STM32F407 的 CAN2(CAN1 为主模式)。
需要修改哪些文件?波特率要求 500Kbps,使用中断接收模式。
需要考虑:GPIO 引脚配置、CAN 波特率时序参数计算、
中断处理、接收 FIFO 溢出处理、与现有 CAN1 的资源共享。
创建一个实施计划。
第三阶段:实现(普通模式)
按照计划实现 OAuth 流程。为回调处理器编写测试,
运行测试套件并修复所有失败。
嵌入式实现示例:
按照计划实现 CAN2 驱动。包括:
1. 在 can_driver.c/h 中实现 CAN2 初始化、发送、接收函数
2. 在 stm32f4xx_it.c 中添加 CAN2 RX 中断处理
3. 在 FreeRTOS 中创建 CAN 接收处理任务
4. 编译验证:运行 make all,修复所有编译错误和警告
5. 使用 make cppcheck 进行静态分析
注意不要使用动态内存分配,所有缓冲区使用静态数组。
第四阶段:提交
用描述性消息提交并创建 PR
何时跳过规划
- 小改动(拼写修正、日志行、重命名)
- 范围明确的单文件修改
- 清晰已知的解决方案
- 一句话就能描述的任务
嵌入式跳过规划的示例:
# 以下任务可以直接执行,无需规划
把 UART1 的波特率从 9600 改为 115200
添加一个新的 LED 闪烁宏定义
修复 GPIO 初始化中缺少上拉电阻的配置
在 FreeRTOS 任务中添加一个 vTaskDelay 调用
并行会话策略
编写者/审查者模式:
- 会话 A:实现代码
- 会话 B:审查代码(全新上下文,无偏见)
扇出模式:
# 生成需要修改的文件列表
# 对每个文件调用 claude -p
# 使用 --allowedTools 限制权限
# 先在少数文件上测试,再大规模运行
嵌入式扇出模式示例:
# 批量为所有驱动文件添加 MISRA-C 注释
find Drivers/ -name "*.c" | while read f; do
claude -p "为 $f 添加 MISRA-C:2012 必要的注释,包括模块描述、函数参数说明和返回值说明" \
--allowedTools Edit,Read \
--permission-mode auto
done
# 批量检查所有中断处理函数的规范性
find . -name "stm32f4xx_it.c" | while read f; do
claude -p "审查 $f 中的中断服务程序,检查是否存在阻塞调用和优先级问题"
done
非交互式集成
# 一次性查询
claude -p "解释这个项目是做什么的"
# 结构化输出
claude -p "列出所有 API 端点" --output-format json
# 管道集成
claude -p "<提示>" --output-format json | your_command
嵌入式非交互式集成示例:
# 分析编译输出中的警告
make all 2>&1 | claude -p "分析这些编译警告,按严重程度排序并给出修复建议"
# 分析 .map 文件中的内存占用
claude -p "分析 @build/firmware.map,列出 RAM 占用最大的前 10 个模块和 Flash 占用最大的前 10 个模块"
# 分析串口日志
cat serial_log.txt | claude -p "分析这段串口日志,找出异常和错误信息,判断是否与 FreeRTOS 栈溢出有关"
# 生成外设配置代码(快速原型)
claude -p "生成 STM32F407 的 TIM3 定时器配置代码,PWM 模式,频率 10KHz,占空比 50%,通道 1 输出到 PA6"
# 分析崩溃堆栈
arm-none-eabi-addr2line -e build/firmware.elf 0x08002A3C 0x08001F51 | \
claude -p "根据地址解析结果分析 HardFault 崩溃位置和原因"
6. 上下文与记忆管理
为什么上下文管理很重要
- 上下文窗口会被消息、文件内容、命令输出填满
- 性能随上下文填充而下降
- 单次调试会话可能消耗数万个 token
上下文管理策略
| 操作 | 命令 | 适用场景 |
|---|---|---|
| 重置上下文 | /clear |
切换到不相关的任务 |
| 手动压缩 | /compact 保留 API 变更部分 |
上下文快满但任务未完成 |
| 回退检查点 | Esc+Esc 或 /rewind |
Claude 走错方向时 |
| 委托调查 | 使用子代理 | 避免调查填满主上下文 |
嵌入式开发上下文管理示例:
/clear # 切换任务,如从写驱动切换到调试
/compact 保留当前寄存器配置和时序参数 # 压缩但保留关键硬件参数
/compact 保留 FreeRTOS 任务列表和栈大小 # 压缩但保留内存分析上下文
常见上下文失败模式
| 问题 | 表现 | 解决方案 |
|---|---|---|
| 大杂烩会话 | 一个会话混多个任务 | 任务间使用 /clear |
| 反复纠正 | 上下文充满失败尝试 | 超过 2 次修正后 /clear 重写提示词 |
| 过度探索 | "调查"没有范围限制 | 缩小范围或使用子代理 |
| CLAUDE.md 太长 | 规则被忽略 | 精简内容,只写必要的 |
嵌入式开发常见上下文问题:
| 问题 | 表现 | 解决方案 |
|---|---|---|
| 数据手册太长 | 读取整个 PDF 填满上下文 | 只引用相关章节或寄存器地址 |
| 反复调试硬件 | 上下文充满失败的配置尝试 | /clear 后提供最终的示波器/逻辑分析仪观测结果 |
| .map 文件过大 | 解析整个 map 文件消耗大量 token | 用 grep 预过滤后再让 Claude 分析 |
/compact 自定义指令
在 CLAUDE.md 中添加:
压缩对话时,始终保留已修改文件的完整列表。
7. 权限与安全
权限模式
| 模式 | 说明 |
|---|---|
| 默认模式 | 文件写入、Bash 命令、MCP 工具都需要确认。安全但繁琐 |
| 自动模式 | 分类器审查命令后执行。阻止范围升级、未知基础设施、恶意内容;允许常规操作 |
切换方式: Shift+Tab 或 --permission-mode auto
权限白名单配置
在 .claude/settings.json 中:
{
"permissions": {
"allowedTools": {
"Bash": ["git commit *", "npm run lint", "npm test"],
"Edit": ["*.ts", "*.js"],
"MCP": ["notion:*", "figma:*"]
}
}
}
嵌入式项目权限配置示例:
{
"permissions": {
"allowedTools": {
"Bash": [
"make all",
"make clean",
"make cppcheck",
"arm-none-eabi-size *",
"arm-none-eabi-objdump *",
"git commit *",
"git diff *",
"git log *"
],
"Edit": ["*.c", "*.h", "*.ld", "Makefile", "CMakeLists.txt"],
"Read": ["*"]
}
}
}
注意:make flash 和 make debug 等涉及硬件操作的命令不要加入白名单,防止误操作烧录或影响正在运行的设备。
沙箱
- 操作系统级别隔离
- 限制文件系统和网络访问
- 允许 Claude 在边界内自由工作
- 使用
/sandbox配置
安全最佳实践
- 不要让 Claude 处理包含密钥的
.env文件 - 使用权限白名单配置常规命令
- CI/CD 中使用
--allowedTools限制能力 - 审查钩子脚本后再提交到敏感仓库
- 对话默认仅本地存储,不用于训练
嵌入式安全额外注意事项:
- 不要将硬件密钥(如 JTAG 密钥、加密芯片密钥)写入 CLAUDE.md 或代码中
- 不要让 Claude 直接执行
make flash/openocd -f flash等烧录命令 - 审查 Claude 生成的中断优先级配置,错误的优先级可能导致系统死锁
- 涉及安全关键代码(如看门狗配置、安全启动)时,务必人工仔细审查
- 不要将产品序列号、设备证书等敏感信息传入 Claude
8. 高级技巧与隐藏功能
快速模式
- 使用
/fast切换 - 同一 Opus 4.6 模型,输出速度更快
- 适合快速迭代、代码探索
Git 历史分析
查看 ExecutionFactory 的 git 历史,
总结其 API 是如何演变成现在这样的
嵌入式 Git 分析示例:
查看 FreeRTOSConfig.h 的 git 历史,重点分析以下配置的变更:
- configTOTAL_HEAP_SIZE 的变化(是否因为内存不足调整过)
- configTICK_RATE_HZ 的变化
- configMAX_SYSCALL_INTERRUPT_PRIORITY 的变化
总结每次变更的原因(从 commit message 推断)。
代码审查模式
你觉得这个文件有哪些可以改进的地方?
嵌入式代码审查示例(CAN 驱动专项):
审查 @Drivers/can/can_driver.c,重点关注:
1. 发送超时处理是否完善(CAN 总线 off 恢复机制)
2. 接收滤波器配置是否有遗漏的标准帧/扩展帧
3. 错误计数器处理是否符合 CAN 2.0B 规范
4. 是否存在在中断中做过多处理的问题
5. 内存对齐是否正确(CAN 消息结构体在 DMA 中的对齐要求)
嵌入式全面代码审查示例(推荐作为自定义 Skill):
对 @Drivers/spi/spi_master.c 进行全面代码审查,按以下维度逐一检查并输出报告:
## 一、内存安全
1. 数组越界:检查所有数组下标访问是否有边界检查,循环变量是否会越界
- 特别关注接收缓冲区的长度校验
- DMA 传输长度与缓冲区大小是否匹配
- 字符串操作(strcpy/strcat)是否可能越界
2. 野指针:检查所有指针使用前是否已正确初始化
- 函数返回后指针是否已置 NULL
- free/vPortFree 后指针是否立即置 NULL(防止 use-after-free)
- 未初始化的指针是否直接使用
3. 栈空间:评估函数调用栈深度
- 局部数组是否过大(应改为 static 或动态分配)
- 递归调用深度是否可控
- 是否适合在 FreeRTOS 任务中调用(考虑任务栈剩余空间)
4. 内存泄漏:检查所有 malloc/pvPortMalloc 是否有对应的 free/vPortFree
- 异常退出路径(错误处理分支)是否遗漏释放
## 二、并发与中断安全
5. 中断优先级:
- ISR 中调用的 FreeRTOS API 是否使用了 FromISR 版本
- 中断优先级是否 >= configMAX_SYSCALL_INTERRUPT_PRIORITY
- 多个中断之间的优先级关系是否合理(如 UART 接收优先级应高于定时器)
6. 互斥锁与资源共享:
- 共享资源(全局变量、外设寄存器)是否使用了互斥保护
- 临界区(taskENTER_CRITICAL/taskEXIT_CRITICAL)是否成对出现
- 是否存在死锁风险(多锁场景下的获取顺序)
- volatile 关键字是否正确使用(ISR 与主循环共享的变量)
7. 中断处理:
- ISR 中是否调用了阻塞函数(HAL_Delay、printf、mutex take)
- 中断标志清除顺序是否正确
- 嵌套中断配置是否安全
## 三、代码规范与可读性
8. 代码规范性:
- 命名是否一致(函数名、变量名、宏定义的风格是否统一)
- 是否符合 MISRA-C:2012 强制规则(如条件表达式不能使用赋值、switch 必须有 default)
- 魔术数字是否替换为有意义的宏或枚举(如 `if (reg & 0x01)` → `if (reg & USART_SR_RXNE_FLAG)`)
- 函数长度是否合理(建议不超过 50 行,超过则拆分)
9. 可读性:
- 代码逻辑是否清晰,是否有过深嵌套(超过 3 层 if)
- 条件判断是否容易理解(复杂条件建议提取为命名良好的函数)
- 函数职责是否单一
- 变量名是否自描述(避免 a, b, tmp, data 这类无意义命名)
10. 注释质量:
- 函数头注释是否完整(功能描述、参数说明、返回值、注意事项)
- 关键算法/时序是否有行内注释说明
- 注释是否与代码一致(修改代码时是否同步更新了注释)
- 是否有过多无用注释(如 `i++; // i 加 1`)
- 硬件相关操作是否有数据手册章节引用
## 四、C 语言标准与类型安全
11. C 标准合规性:
- 是否使用了正确的 C 标准特性(本项目使用 C99/C11)
- 是否混用了不同宽度的类型(如 int vs int32_t,应统一使用 stdint.h 定义的类型)
- 是否有隐式类型转换导致的精度丢失或符号问题
- 枚举类型是否用于定义有限状态和错误码
- 结构体是否有适当的对齐和打包属性(__attribute__((packed)))
- 移位操作是否有未定义行为(如对有符号数左移)
- 是否正确使用了 static(限制作用域)和 const(不可变修饰)
## 五、硬件与外设相关
12. 外设配置正确性:
- GPIO 引脚复用是否正确
- 时钟使能是否遗漏
- DMA 配置(源地址、目标地址、传输方向、数据宽度)是否正确
- 看门狗喂狗间隔是否合理
输出格式:按严重程度分级(严重/警告/建议),每条包含行号、问题描述和修改建议。
快速代码审查示例(单次对话使用):
审查 @Middleware/protocol/modbus_slave.c,重点检查:
1. 接收缓冲区是否有越界风险(Modbus 帧长度校验)
2. 指针初始化和空指针检查
3. CRC 校验函数的边界处理
4. 是否有在中断中修改且在任务中读取的共享变量(需 volatile)
5. 错误码是否用枚举定义而非魔术数字
代码库入门
把你想问高级工程师的问题都问出来
非常适合新项目上手,减少对团队成员的打扰。
嵌入式代码库入门示例:
我刚接手这个 STM32 项目,帮我了解:
1. 整体软件架构是什么?分层结构是怎样的?
2. 用了哪些通信协议栈?(CAN/UART/SPI/I2C/USB 以太网)
3. FreeRTOS 一共创建了哪些任务?各自的职责是什么?
4. 中断优先级是如何分配的?哪些中断优先级最高?
5. Bootloader 和 App 的 Flash 分区是怎样的?
6. 低功耗模式是如何管理的?唤醒源有哪些?
视觉验证
- 使用 Claude in Chrome 扩展
- 在真实浏览器中测试 UI 修改
- 截图对比工作流
管道操作
# 将错误日志传给 Claude 分析
cat error.log | claude
# 结构化输出用于后续处理
claude -p "分析依赖关系" --output-format json | jq '.dependencies'
嵌入式管道操作示例:
# 分析编译后的 section 大小
arm-none-eabi-size build/firmware.elf | claude -p "分析这个固件的 Flash 和 RAM 占用是否合理"
# 比较两次编译的固件大小差异
diff <(arm-none-eabi-size build/old.elf) <(arm-none-eabi-size build/new.elf) | \
claude -p "分析固件大小变化"
# 从 map 文件中提取指定模块的信息
grep -A 5 "can_driver" build/firmware.map | \
claude -p "分析 CAN 驱动模块的内存占用情况"
# 反汇编指定函数
arm-none-eabi-objdump -d build/firmware.elf | grep -A 30 "<HardFault_Handler>:" | \
claude -p "分析这个 HardFault_Handler 的汇编实现"
桌面应用
- 多个并行会话
- 每个会话独立的 worktree
- 可视化会话切换
- 支持计划任务(定时自动运行)
9. 插件与工具集成
Claude Code 通过插件(Plugins)和 MCP(Model Context Protocol)服务器与外部工具集成,极大扩展了开发能力。
插件系统
插件是社区或官方提供的扩展包,可以通过 /plugin 命令浏览和安装。
常用插件分类:
| 类别 | 代表插件 | 用途 |
|---|---|---|
| 代码质量 | linter、formatter | 自动检查和格式化代码 |
| 测试 | test-runner、coverage | 自动运行测试和覆盖率分析 |
| 文档 | doc-generator | 自动生成 API 文档 |
| Git 增强 | git-flow、changelog | 规范化 Git 工作流 |
| 项目管理 | jira、linear | 集成任务管理工具 |
使用方式:
/plugin # 浏览可用插件
/plugin install <name> # 安装插件
/plugin list # 查看已安装插件
MCP Servers 详解
MCP(Model Context Protocol)让 Claude Code 能够直接调用外部工具和数据源。
常用 MCP Server 配置
通用开发工具:
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_TOKEN": "your-token" }
},
"gitlab": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-gitlab"],
"env": { "GITLAB_TOKEN": "your-token" }
},
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir"]
},
"database": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-sqlite", "path/to/db.sqlite"]
},
"brave-search": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-brave-search"],
"env": { "BRAVE_API_KEY": "your-key" }
},
"memory": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-memory"]
}
}
}
嵌入式开发相关 MCP Server 配置:
{
"mcpServers": {
"serial-monitor": {
"command": "python",
"args": ["tools/mcp_serial_server.py"],
"description": "串口日志实时读取和分析"
},
"firmware-analyzer": {
"command": "python",
"args": ["tools/mcp_firmware_analyzer.py"],
"description": "分析 .elf/.map/.hex 文件"
},
"jira": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-jira"],
"env": { "JIRA_API_TOKEN": "your-token" },
"description": "集成 Jira 缺陷跟踪系统"
}
}
}
自定义 MCP Server 开发(嵌入式串口监控示例)
创建 tools/mcp_serial_server.py:
#!/usr/bin/env python3
"""
嵌入式开发 MCP Server - 串口日志监控
功能:读取串口日志、分析异常、解析协议数据
"""
import serial
import json
import sys
from mcp.server import Server
server = Server("serial-monitor")
@server.tool("read_serial")
def read_serial(port: str, baudrate: int = 115200, timeout: float = 5.0) -> str:
"""读取串口数据并返回最近 N 行日志"""
ser = serial.Serial(port, baudrate, timeout=timeout)
lines = []
for _ in range(100): # 读取最近 100 行
line = ser.readline().decode('utf-8', errors='replace').strip()
if line:
lines.append(line)
ser.close()
return "\n".join(lines)
@server.tool("analyze_serial_log")
def analyze_serial_log(log_file: str) -> str:
"""分析串口日志文件,提取错误和异常"""
with open(log_file, 'r') as f:
content = f.read()
errors = []
for i, line in enumerate(content.split('\n'), 1):
if any(kw in line.upper() for kw in ['ERROR', 'FAULT', 'HARDFAULT', 'ASSERT', 'STACK']):
errors.append(f"Line {i}: {line}")
return f"发现 {len(errors)} 个异常:\n" + "\n".join(errors) if errors else "未发现异常"
if __name__ == "__main__":
server.run()
静态分析工具集成
Cppcheck 集成
# 安装
sudo apt install cppcheck # Linux
choco install cppcheck # Windows
# 通过 Claude Code 使用
claude -p "运行 cppcheck 分析 Drivers/ 目录下的所有 C 文件,解释每个警告的含义并给出修复建议"
示例提示词:
运行以下命令分析代码质量:
cppcheck --enable=all --suppress=missingIncludeSystem --language=c \
--std=c99 --platform=unix32 \
-I Inc/ -I Drivers/ \
--addon=misra.py \
Drivers/ Core/ Middleware/
分析输出结果,按以下优先级分类:
1. 错误(error):必须修复
2. 未定义行为(undefinedBehavior):必须修复
3. 风格问题(style):建议修复
4. 性能问题(performance):评估后修复
5. 可移植性问题(portability):评估后修复
6. MISRA-C 违规:按规则编号列出
clang-tidy 集成
# 安装
sudo apt install clang-tidy # Linux
# Windows: 随 LLVM/Clang 安装
# 通过 Claude Code 使用
claude -p "使用 clang-tidy 检查 src/main.c,使用 .clang-tidy 配置文件,解释每个检查结果"
clang-tidy 配置文件示例(.clang-tidy):
Checks: >
-*,
bugprone-*,
cert-*,
clang-analyzer-*,
cppcoreguidelines-*,
misc-*,
modernize-*,
performance-*,
readability-*,
-modernize-use-trailing-return-type
HeaderFilterRegex: '.*'
PC-lint / FlexeLint 集成
# 适合大型嵌入式项目的商业静态分析工具
claude -p "运行 PC-lint 分析整个项目,使用 co-gcc.lnt 配置,
分析输出结果并按严重程度(Error/Warning/Info/Note)分类,
特别关注 MISRA-C:2012 的违规项"
构建系统集成
Makefile + Claude Code
帮我优化项目的 Makefile。当前问题是:
1. 增量编译有时不准确(头文件依赖未追踪)
2. 想添加自动生成依赖关系(-MMD -MP)
3. 添加 `make size` 目标显示各 section 大小
4. 添加 `make map` 目标生成并分析 .map 文件
参考当前的 @Makefile。
CMake + Claude Code
将当前的 Makefile 项目转换为 CMake 项目,要求:
1. 支持交叉编译(arm-none-eabi-gcc 工具链)
2. 支持多种构建类型(Debug/Release)
3. 集成 clang-tidy 和 cppcheck
4. 自动生成编译数据库(compile_commands.json)
5. 支持多目标构建(Bootloader + App)
参考 @toolchain-arm-none-eabi.cmake 的现有配置。
调试工具集成
GDB / OpenOCD
通过 Claude Code 分析 GDB 输出:
# 启动调试会话并捕获输出
arm-none-eabi-gdb build/firmware.elf -ex "target remote :3333" \
-ex "bt" -ex "info registers" -ex "x/20x \$sp" \
> gdb_output.txt 2>&1
# 让 Claude 分析
claude -p "分析这段 GDB 调试输出 @gdb_output.txt,判断崩溃原因:
1. 分析 backtrace 中的调用链
2. 分析寄存器状态(特别是 PC、LR、xPSR、CFSR)
3. 检查栈内容是否合理
4. 判断是 HardFault、MemManage 还是 BusFault"
调试脚本生成:
生成一个 GDB 调试脚本(debug.gdbinit),用于调试 FreeRTOS 应用:
1. 连接 OpenOCD(target remote :3333)
2. 定义命令:显示所有任务列表(通过 vTaskList)
3. 定义命令:显示任务栈使用情况
4. 定义命令:在 HardFault_Handler 设置断点并自动打印寄存器
5. 定义命令:监控指定变量的值变化(watchpoint)
Segger RTT / SystemView
帮我集成 Segger RTT(Real-Time Transfer)调试输出到项目中:
1. 添加 RTT 源码到 Middleware/Segger/ 目录
2. 创建 RTT 封装层,支持 printf 重定向到 RTT
3. 支持 RTT Channel 0 用于普通日志,Channel 1 用于调试数据
4. 添加编译开关:USE_RTT_DEBUG 宏控制是否启用
参考 @Drivers/uart_printf.c 中现有的 printf 实现。
测试工具集成
Unity + CMock(C 语言单元测试)
搭建基于 Unity + CMock 的单元测试框架:
1. 在 tests/ 目录下创建测试框架结构
2. 编写 Makefile 支持 `make unittest`
3. 生成 Mock 文件用于隔离硬件依赖
4. 为 @Drivers/adc/adc_driver.c 编写测试示例
测试场景:
- 正常采样流程
- DMA 传输完成回调
- 超时处理
- 多通道扫描切换
Google Test(C++ 项目)
使用 Google Test 框架为 HAL 封装层编写测试:
1. 配置 CMake 集成 GTest
2. 使用 HAL Mock 类隔离硬件
3. 测试 UART 发送接收逻辑
4. 测试错误处理路径
要求测试覆盖率 > 80%。
文档生成集成
Doxygen
使用 Doxygen 为整个嵌入式项目生成 API 文档:
1. 创建 Doxyfile 配置,适配项目结构
2. 检查现有代码中的注释是否符合 Doxygen 格式
3. 对不符合的函数,添加正确的注释模板
4. 生成 HTML 文档到 docs/html/ 目录
5. 重点关注 Drivers/ 和 Middleware/ 的公开 API
Doxygen 注释规范提示词:
为 @Drivers/spi/spi_master.c 中的所有公开函数添加 Doxygen 注释,
格式如下:
/**
* @brief 简要描述
* @param 参数名 参数描述
* @retval 返回值 返回值描述
* @note 注意事项(硬件限制、使用条件等)
*/
不要修改函数实现,只添加注释。
CI/CD 集成
GitHub Actions(嵌入式固件 CI)
创建 GitHub Actions 工作流,实现嵌入式固件的自动化构建:
1. 触发条件:push 到 main/develop 分支,或 PR
2. 构建步骤:
- 安装 arm-none-eabi-gcc 工具链
- make all
- make unittest
- make cppcheck
3. 产物:firmware.hex + firmware.bin
4. 报告:编译警告数、固件大小、测试覆盖率
5. 使用 claude -p 在 CI 中做代码审查
参考现有的 @.github/workflows/ 配置。
GitLab CI 示例
# .gitlab-ci.yml 嵌入式固件 CI 示例
stages:
- build
- test
- analyze
- deploy
build_firmware:
stage: build
image: gcc-arm-embedded:latest
script:
- make all
- arm-none-eabi-size build/firmware.elf
artifacts:
paths:
- build/firmware.hex
- build/firmware.bin
- build/firmware.map
run_tests:
stage: test
script:
- make unittest
- make coverage
static_analysis:
stage: analyze
script:
- make cppcheck 2>&1 | tee cppcheck_report.txt
- claude -p "分析这个静态分析报告 @cppcheck_report.txt,标注必须修复的项"
代码格式化集成
clang-format
.clang-format 配置文件(嵌入式 C 项目推荐):
BasedOnStyle: LLVM
Language: Cpp
IndentWidth: 4
TabWidth: 4
UseTab: Never
BreakBeforeBraces: Allman
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: false
AlignConsecutiveMacros: true
SpaceBeforeParens: ControlStatements
ColumnLimit: 100
通过 Claude Code 使用:
为整个项目统一代码格式:
1. 先在项目根目录创建 .clang-format 配置文件
2. 对所有 .c 和 .h 文件运行 clang-format
3. 用 git diff 查看变更,确认格式化结果合理
4. 注意不要格式化第三方库代码(CMSIS/、Middlewares/Third_Party/)
版本管理与发布
语义版本号管理
帮我管理固件版本号:
1. 在 firmware_version.h 中定义版本宏
2. 实现 version_print() 函数,通过串口输出版本信息
3. 在 Makefile 中支持通过命令行覆盖版本号:make VERSION=1.2.3
4. 在启动日志中自动打印版本号和编译时间
5. 集成到 Git tag 流程中
变更日志生成
# 自动生成 changelog
claude -p "分析从 v1.2.0 到 HEAD 的所有 git 提交,按以下分类生成 CHANGELOG.md:
- 新功能(feat/)
- Bug 修复(fix/)
- 重构(refactor/)
- 文档更新(docs/)
格式参考 @CHANGELOG.md 的现有风格。"
功能选择指南(更新版)
| 需求 | 使用 |
|---|---|
| 项目全局约定 | CLAUDE.md |
| 领域知识、可复用工作流 | Skills(技能) |
| 必须每次执行的动作 | Hooks(钩子) |
| 隔离调查/审查 | Subagents(子代理) |
| 外部工具集成 | MCP Servers |
| 社区扩展包 | Plugins(插件) |
| 无中断可信工作流 | Auto 模式 |
| 复杂多文件变更 | Plan 模式 |
| 代码静态分析 | cppcheck / clang-tidy |
| 自动化构建 | CI/CD + claude -p |
| 调试辅助 | GDB 脚本 + claude 分析 |
| 代码格式化 | clang-format + post_edit Hook |
| 文档生成 | Doxygen + claude 注释补全 |
| 单元测试 | Unity/CMock + claude 生成测试 |
| 版本管理 | Git tag + 语义版本号 |
10. 多人协同开发
Claude Code 不仅是个人开发工具,在团队协作中也能大幅提升效率。本章介绍多人协同场景下的配置、工作流和提示词模板。
团队统一配置
必须提交到 Git 的文件
project/
├── .claude/
│ ├── settings.json # 团队共享的权限和 MCP 配置
│ ├── skills/ # 团队共享的自定义技能
│ │ ├── review-code/SKILL.md
│ │ ├── fix-issue/SKILL.md
│ │ └── analyze-crash/SKILL.md
│ └── agents/ # 团队共享的子代理
│ ├── memory-analyzer.md
│ └── code-reviewer.md
├── CLAUDE.md # 项目级约定(团队共享)
├── .clang-format # 统一代码格式化规则
├── .clang-tidy # 统一静态分析规则
└── .gitignore # 确保 .claude/settings.local.json 被忽略
不应提交的文件(加入 .gitignore)
.claude/settings.local.json # 个人权限配置
.claude/statsig/ # 个人使用统计
CLAUDE.local.md # 个人笔记
团队 CLAUDE.md 模板(嵌入式项目)
# 项目约定 —— 团队必读
## 团队角色与模块划分
- 张三:Drivers/ 驱动层(SPI/I2C/UART/CAN)
- 李四:Middleware/ 中间件(Modbus/FreeRTOS/文件系统)
- 王五:App/ 应用层(业务逻辑/HMI)
- 赵六:Bootloader/ 引导加载程序
- 任何人修改他人模块前,必须先在群里通知并说明原因
## 代码提交规范
- commit message 格式:[模块] 类型: 描述
- 例:[CAN] fix: 修复 CAN2 接收 FIFO 溢出后未恢复的 bug
- 例:[SPI] feat: 添加 DMA 双缓冲传输支持
- 例:[App] refactor: 重构温度采集任务的状态机
- 类型:feat/fix/refactor/docs/test/chore
- 每次提交前必须通过 `make cppcheck` 和 `make unittest`
## 分支策略
- main:稳定发布分支,只接受 PR 合入
- develop:开发集成分支
- feat/xxx:新功能分支,从 develop 创建
- fix/xxx:bug 修复分支,从 develop 或 main(紧急修复)创建
- 分支命名示例:feat/can-fd-support、fix/spi-dma-timeout
## Code Review 规则
- 所有 PR 必须至少一人审查通过
- 驱动层修改需要张三审查
- 中间件修改需要李四审查
- 涉及中断优先级或 RTOS 配置的修改,需要全组审查
- 使用 Claude Code 的 /review-code 技能辅助审查
## API 接口变更流程
1. 先在 docs/api_changes.md 中记录变更意图
2. 修改头文件中的接口声明,添加 @deprecated 标注旧接口
3. 保持向后兼容至少一个版本
4. 通知所有受影响的模块负责人
## 调试信息约定
- 日志级别:ERROR > WARN > INFO > DEBUG > TRACE
- 格式:[级别][模块][行号] 消息
- 例:[ERROR][CAN][245] CAN2 RX FIFO overflow, resetting...
- 禁止在发布版本中使用 printf,使用 LOG_xxx 宏
## 硬件相关约定
- 不要直接操作寄存器,统一通过 BSP 层接口
- 新增外设使用前,先在 hal_resource_table.md 中登记资源占用
- 中断优先级分配表见 docs/interrupt_priority.md,新增中断必须更新
多人并行开发工作流
场景一:多模块并行开发
问题: 团队多人同时开发不同模块,互不干扰。
提示词模板:
我要在 feat/adc-sampling 分支上开发 ADC 多通道采样功能。
这个功能位于 Drivers/ADC/ 目录,与其他模块的接口只有 App/task_adc.c。
请帮我:
1. 分析我需要修改和新增的文件列表
2. 列出可能与他人正在开发的模块产生冲突的地方
3. 建议如何设计接口使我的开发不影响他人
4. 生成模块间的接口头文件(adc_types.h),供他人提前引用
我需要在以下接口上与其他人协调:
- SPI 驱动(张三负责):我需要 DMA 通道,需确认不冲突
- App 层(王五负责):我会提供新的 ADC 采样 API,需确认接口
嵌入式多模块协调示例:
我们团队有以下并行开发任务:
- 张三:正在重构 SPI 驱动(影响 drivers/spi/)
- 李四:正在添加 Modbus TCP 支持(影响 middleware/modbus/)
- 我:需要添加 ADC 数据通过 DMA 传输到 SPI 发送的功能
帮我分析:
1. 我需要使用 DMA2 Stream3 Channel0,检查是否与张三的 SPI 驱动有 DMA 资源冲突
2. 我需要在 SPI 发送中断中触发 ADC 转换完成回调,这会影响张三的重构吗?
3. 李四的 Modbus TCP 需要读取 ADC 数据,我应该提供怎样的数据接口?
4. 画出这三个模块的依赖关系和接口交互图
场景二:接口联调
提示词模板:
张三已经完成了 SPI 驱动的重构(分支 feat/spi-refactor),
我需要将我的 SPI Flash 驱动适配到新接口。
请帮我:
1. 对比 feat/spi-refactor 分支和 develop 分支的 @drivers/spi/spi_driver.h 接口差异
2. 列出我这边需要修改的所有调用点
3. 生成适配代码,保持功能不变
4. 编写兼容性测试确认新旧接口行为一致
git diff develop...feat/spi-refactor -- drivers/spi/
嵌入式接口联调示例:
我和李四的模块需要联调。他负责 CAN 消息的接收解析,
我负责根据解析结果执行电机控制。
当前状态:
- 李四已经提交了 CAN 解析 API(见 @middleware/can_parser.h)
- 我需要调用他的 API 获取解析后的电机命令
请帮我:
1. 读取 @middleware/can_parser.h,理解他提供的数据结构和 API
2. 在 @app/motor_control.c 中集成调用
3. 设计错误处理:如果 CAN 解析返回数据异常,电机应进入安全状态
4. 确认我们的数据结构定义是一致的(特别是电机命令枚举和速度单位)
5. 生成联调测试步骤清单
场景三:解决合并冲突
提示词模板:
我在合并 develop 分支到我的 feat/adc-sampling 分支时出现了冲突。
请帮我分析冲突文件并解决:
1. 查看冲突文件列表(git status)
2. 分析每个冲突的原因和双方的修改意图
3. 合理地解决冲突,保留双方的有效修改
4. 确认解决后代码能编译通过
特别注意:
- 不要丢失任何一方的功能代码
- 如果冲突涉及中断优先级分配,保持最新的分配表
- 如果冲突涉及 FreeRTOS 任务优先级,保持最新的配置
嵌入式合并冲突处理示例:
合并 develop 时 FreeRTOSConfig.h 出现了冲突。
我修改了 configTOTAL_HEAP_SIZE(从 20KB 改为 30KB,因为新增了 ADC 缓冲区),
develop 分支也修改了这个值(改为 25KB,因为李四的 Modbus 模块需要更多堆内存)。
请帮我:
1. 计算合并后实际需要的堆大小(ADC 缓冲区 10KB + Modbus 5KB + 其他 20KB = 35KB)
2. 检查芯片 RAM 是否足够(STM32F407 有 192KB RAM)
3. 更新 FreeRTOSConfig.h 中的 configTOTAL_HEAP_SIZE
4. 同时检查是否有其他配置也需要同步更新(如任务栈大小)
场景四:Code Review(交叉审查)
使用 Claude Code 辅助 Code Review 的提示词模板:
帮我审查这个 PR 的变更。
审查范围:git diff develop...feat/adc-sampling
重点检查:
1. 新增的 ADC 驱动是否遵循项目已有的驱动架构模式
2. DMA 配置是否正确且不与其他外设冲突
3. 中断优先级设置是否符合 docs/interrupt_priority.md 的分配表
4. 新增的 FreeRTOS 任务栈大小是否合理
5. 是否有内存泄漏风险(特别是动态分配的缓冲区)
6. 错误处理路径是否完善(ADC 转换超时、DMA 传输错误)
7. 接口文档是否同步更新
输出格式:按模块分组,每条包含严重程度、文件名:行号、问题描述、修改建议。
嵌入式 Code Review 专项提示词:
审查驱动的提示词:
审查 @Drivers/ADC/adc_dma_driver.c,这是团队新成员提交的 ADC DMA 驱动。
检查清单:
1. 资源冲突:DMA 通道是否已在 hal_resource_table.md 中登记
2. 线程安全:ADC 启动/停止接口是否可从多个任务调用
3. 中断安全:ADC 转换完成回调中是否只做必要操作(发送信号量,不做数据处理)
4. 错误恢复:ADC 校准失败、DMA 传输错误、ADC 溢出的恢复机制
5. 时序要求:采样率配置是否会导致 ADC 转换时间不足
6. 内存对齐:DMA 缓冲区是否对齐到 32 字节(D-Cache 兼容)
7. 低功耗:ADC 是否支持在 Stop 模式下自动关闭、唤醒后自动恢复
严重级别标准:
- 阻塞(Block):必须修改后才能合并(安全/功能问题)
- 建议(Suggest):建议修改(性能/可维护性改进)
- 讨论(Discuss):需要和提交者讨论的设计选择
审查 RTOS 相关代码的提示词:
审查 @Core/Src/freertos.c 中新增的 ADC 采样任务。
重点检查:
1. 任务栈大小:
- 分析该任务的最大调用深度
- 局部变量大小(数组等)
- 建议使用 uxTaskGetStackHighWaterMark() 进行运行时验证
2. 任务优先级:
- ADC 采样任务的优先级是否高于数据处理任务
- 是否会饿死其他低优先级任务
3. 同步机制:
- 使用了信号量还是事件组?选择是否合理?
- 等待超时设置是否合理(太短会频繁超时,太长会影响响应)
4. 与中断的交互:
- 是否正确使用了 xSemaphoreGiveFromISR
- portYIELD_FROM_ISR 的使用是否正确
分支与发布管理
版本发布前的全员检查
我们准备发布 v2.1.0 版本,需要做发布前检查。
请帮我执行以下检查:
1. 确认所有团队成员的 feature 分支都已合并到 develop
2. 检查 git log develop --since="2 weeks ago" 的提交记录是否完整
3. 运行 make all && make unittest && make cppcheck,确认全部通过
4. 对比 v2.0.0 到现在的固件大小变化:arm-none-eabi-size
5. 检查 CLAUDE.md 中的版本号是否需要更新
6. 检查 CHANGELOG.md 是否覆盖了所有变更
7. 确认所有外设资源分配表是最新的
如果发现任何阻塞问题,立即报告。
紧急 hotfix 流程
线上设备出现了 HardFault,需要紧急修复。
紧急修复流程:
1. 先从 main 分支创建 fix/hardfault-xxx 分支
2. 分析崩溃信息:@crash_log.txt
3. 定位问题并修复(只做最小修改,不做重构)
4. 运行 make all && make cppcheck 确认编译通过
5. 提交并创建 PR 到 main,标记为紧急
6. 同时通知全组:这个修复是否影响其他人在开发的功能
修复原则:
- 最小改动原则,不引入新功能
- 必须添加防止同类问题的防御性检查
- 在注释中标注关联的 bug 编号
远程协作场景
异步代码交接
当你需要把一个模块交接给同事,或接手别人的模块时:
交接方提示词:
我要把 CAN 驱动模块交接给同事。请帮我生成交接文档:
分析 @Drivers/can/ 目录下的所有文件,生成以下内容:
1. 模块概述:功能、设计思路、依赖关系
2. 已知问题列表:搜索所有 TODO、FIXME、HACK 注释
3. 待办事项:列出未完成的功能和已知的限制
4. 性能瓶颈:标注可能需要优化的地方
5. 测试情况:哪些场景已验证,哪些还需补充测试
6. 外部依赖:列出让同事需要了解的其他模块接口
7. 调试技巧:常用的调试方法和排错经验
将交接文档保存为 docs/handover/can_driver.md
接手方提示词:
我刚接手张三负责的 SPI 驱动模块(@Drivers/SPI/)。
请帮我快速上手:
1. 生成模块架构图:哪些文件、函数之间的调用关系
2. 列出所有公开 API 及其用途
3. 指出代码中最复杂/最易出错的部分
4. 检查最近的 git 提交,了解最近的修改方向
5. 搜索所有 TODO 和 FIXME,了解遗留问题
6. 运行 make cppcheck,检查是否有静态分析问题
然后给我一个建议的学习路径,从易到难了解这个模块。
Code Review 异步协作
张三提交了一个 PR(#42),修改了 SPI 驱动的 DMA 传输逻辑。
我需要在 Claude Code 中帮他做详细的 Code Review。
步骤:
1. 使用 gh pr view 42 查看 PR 描述
2. 使用 gh pr diff 42 查看变更内容
3. 对照项目 CLAUDE.md 中的代码规范进行检查
4. 特别关注 DMA 配置变更(这是高风险操作)
5. 生成审查意见,按 Block/Suggest/Discuss 分类
6. 使用 gh pr review 42 提交审查意见
注意:张三使用的 DMA 通道和我的 ADC 模块有冲突的话,需要标记为 Block。
会议与文档协作
技术方案评审
我需要准备下周的技术评审会议材料。
主题:将固件从裸机架构迁移到 FreeRTOS。
请帮我生成评审文档,包含以下内容:
1. 现状分析(读取当前项目架构)
2. 迁移方案(分阶段迁移计划)
3. 风险评估(哪些模块迁移风险高)
4. 资源影响(RAM/Flash 占用变化估算)
5. 工期估算(各模块的工作量)
6. 回退方案(如果迁移出问题如何回滚)
7. 测试策略(每个阶段的验证方法)
参考项目中的:
- @Core/Src/main.c(当前裸机主循环)
- @Core/Src/stm32f4xx_it.c(当前中断处理)
- @Makefile(构建配置)
- @stm32f407.ld(内存布局)
输出为 docs/review/rtos_migration.md
接口协议文档生成
我们团队正在开发一个多板通信项目,需要定义板间通信协议。
请根据以下需求生成协议文档:
1. 主板(STM32F407)通过 SPI 与从板(STM32F103)通信
2. 通信内容:传感器数据、控制命令、状态反馈
3. 要求:CRC16 校验、超时重传、帧序号防重复
生成内容:
- 帧格式定义(头帧、数据帧、应答帧)
- 数据结构定义(C 语言头文件格式,供双方共用)
- 状态机设计(发送端和接收端)
- 错误处理机制
- 时序图(ASCII 或文字描述)
保存到 docs/protocol/spi_board_comm.md
同时生成公共头文件到 Shared/protocol_types.h
团队工作流最佳实践
| 场景 | 推荐做法 | 提示词关键词 |
|---|---|---|
| 新人入职 | 用 Claude 生成模块导读和架构图 | “生成模块架构图”、“列出学习路径” |
| 接手他人代码 | 先分析后修改,生成交接文档 | “模块概述”、“已知问题”、“调试技巧” |
| 并行开发不同模块 | 明确接口、减少耦合 | “接口设计”、“资源冲突”、“依赖分析” |
| 联调集成 | 先自测接口再联调 | “接口差异”、“兼容性”、“联调测试” |
| Code Review | 用子代理无偏见审查 | “按严重程度分级”、“检查清单” |
| 合并冲突 | 分析双方意图再解决 | “冲突原因”、“保留双方修改” |
| 紧急修复 | 最小改动 + 充分通知 | “最小修改”、“通知全组”、“防御性检查” |
| 版本发布 | 自动化检查 + 全员确认 | “发布前检查”、“阻塞问题” |
| 技术方案评审 | 提前生成文档供讨论 | “风险评估”、“回退方案”、“工期” |
| 接口变更 | 先文档后代码 | “接口变更记录”、“向后兼容”、“通知负责人” |
常见协同问题与解决提示词
问题一:我的代码在别人合并后编译失败
develop 分支合并了李四的 Modbus 模块后,我的 ADC 模块编译失败了。
请帮我:
1. 运行 make all 捕获编译错误
2. 分析每个错误的根本原因(是头文件路径变化?还是 API 签名变了?)
3. 自动修复我能处理的编译错误
4. 对于需要和李四协调的接口变更,列出清单由我与他沟通
问题二:两个人的中断优先级配置冲突
我发现张三的新 SPI 驱动和我刚合并的 CAN 驱动使用了相同的中断优先级(优先级 5)。
请帮我:
1. 读取 @Core/Src/stm32f4xx_it.c 和 @docs/interrupt_priority.md
2. 分析当前所有已分配的中断优先级
3. 检查是否有优先级冲突
4. 根据 FreeRTOS 的 configMAX_SYSCALL_INTERRUPT_PRIORITY 要求,
建议合理的优先级重新分配方案
5. 列出需要通知的团队成员
问题三:固件大小超出 Flash 容量
合并了所有人的代码后,固件大小超出了 512KB Flash 限制。
请帮我分析并优化:
1. 运行 arm-none-eabi-size build/firmware.elf 查看各 section 大小
2. 分析 .map 文件,找出占用 Flash 最大的前 20 个模块/函数
3. 检查是否有可以优化的小模块:
- 未使用但被编译进去的源文件
- printf 的浮点支持(非常占空间)
- 调试日志代码(可用宏开关关闭)
- 过大的查找表(考虑算法替代)
4. 估算每项优化能节省的空间
5. 给出优先级排序的优化建议
11. 多 Agent 协同开发
Claude Code 支持在一个对话中启动多个子代理(Subagent),让它们像团队成员一样分工协作。本章详细介绍如何用提示词编排多 Agent 协同工作流。
多 Agent 协同的基本原理
你(主对话)
├── Agent A(架构设计)──→ 输出设计方案
├── Agent B(代码实现)──→ 输出源代码
├── Agent C(代码审查)──→ 输出审查报告
└── Agent D(测试编写)──→ 输出测试用例
核心概念:
- 主对话:你的对话窗口,负责分发任务和汇总结果
- 子代理(Agent):独立的工作线程,有自己的上下文,不影响主对话
- 并行执行:多个 Agent 可以同时工作,互不干扰
- 结果汇总:Agent 完成后结果返回主对话,由你决定下一步
提示词中触发多 Agent 的方式
方式一:直接请求并行子代理
同时启动以下任务(并行执行):
1. 调查 Drivers/ 目录下所有外设驱动的架构模式,
列出每个驱动的初始化流程和错误处理方式
2. 分析 Middleware/ 目录下的协议栈实现,
列出支持的功能和已知的 TODO 项
3. 审查 Core/Src/stm32f4xx_it.c 中的中断服务程序,
检查是否存在阻塞调用和优先级问题
三个任务互不依赖,请并行执行,最后汇总结果。
方式二:使用自定义 Agent 定义文件
在 .claude/agents/ 目录下预定义多个专业 Agent:
架构分析师 - .claude/agents/architect.md:
---
name: architect
description: 嵌入式系统架构分析师
tools: Read, Grep, Glob
model: opus
---
你是一位资深嵌入式系统架构师。分析代码时你必须:
- 画出模块依赖关系图(ASCII 格式)
- 标注各层的接口边界和数据流向
- 识别架构中的循环依赖和耦合问题
- 评估架构的可扩展性和可维护性
- 输出结构化的架构分析报告
报告格式:
# 架构分析报告
## 1. 模块总览(表格:模块名 | 职责 | 依赖 | 代码行数)
## 2. 依赖关系图
## 3. 问题清单(严重程度 | 模块 | 描述 | 建议)
## 4. 改进建议
驱动实现工程师 - .claude/agents/driver-implementer.md:
---
name: driver-implementer
description: 嵌入式外设驱动实现工程师
tools: Read, Grep, Glob, Edit, Write
---
你是一位嵌入式驱动开发工程师。实现驱动时你必须遵循:
- 参考项目中已有的驱动代码风格(先读取一个现有驱动作为模板)
- 初始化函数必须包含错误检查和返回值
- 所有缓冲区使用静态分配,禁止 malloc
- 中断回调中只做最小操作(发送信号量/事件标志)
- 提供完整的函数头注释(Doxygen 格式)
- 每个公开函数都要有对应的错误码定义
输出要求:
- .c 文件:实现代码
- .h 文件:接口声明 + 类型定义 + 错误码
- 在文件末尾列出可能需要调整的硬件参数
测试工程师 - .claude/agents/test-engineer.md:
---
name: test-engineer
description: 嵌入式测试工程师
tools: Read, Grep, Glob, Write
---
你是一位嵌入式测试工程师。编写测试时你必须:
- 使用 Unity 测试框架
- 使用 CMock 模拟硬件依赖(HAL 函数)
- 覆盖以下测试类型:
1. 正常路径测试(Happy path)
2. 边界条件测试(缓冲区满/空、最大/最小值)
3. 错误路径测试(超时、NACK、总线错误)
4. 并发安全测试(多任务同时访问的场景描述)
测试文件命名:test_<module_name>.c
测试函数命名:test_<function>_<scenario>
每个测试函数只测一个场景。
代码审查员 - .claude/agents/code-reviewer.md:
---
name: code-reviewer
description: 嵌入式代码审查专家
tools: Read, Grep, Glob
model: opus
---
你是一位严格的嵌入式代码审查专家。审查代码时按以下维度逐一检查:
## 审查维度
1. **内存安全**:数组越界、野指针、栈溢出风险、内存泄漏
2. **并发安全**:中断安全、互斥保护、volatile 使用、死锁风险
3. **代码规范**:命名一致性、MISRA-C 合规、魔术数字、函数长度
4. **硬件正确性**:寄存器配置、时钟使能、DMA 配置、引脚复用
5. **错误处理**:所有返回值是否检查、异常路径是否处理
6. **可维护性**:注释质量、模块耦合度、接口清晰度
## 输出格式
每条审查意见必须包含:
- 严重程度:[BLOCK] / [WARN] / [SUGGEST]
- 位置:文件名:行号
- 问题描述:简洁明了
- 修改建议:给出具体的修复代码片段
最后输出审查统计:总问题数、按严重程度分布。
多 Agent 协同实战场景
场景一:新驱动开发全流程
提示词(一次完成设计+实现+测试+审查):
我需要为 STM32F407 开发一个新的 I2C EEPROM 驱动(AT24C256)。
请启动多个 Agent 并行工作:
第一步(并行):
- Agent 1(架构分析师):分析 Drivers/ 目录下现有的驱动架构,
总结 I2C 驱动的标准模式、初始化流程、错误处理规范
- Agent 2(架构分析师):读取 AT24C256 数据手册相关章节(如已提供),
分析其页写入时序、随机读取时序、ACK 轮询要求
第二步(依赖第一步结果):
- Agent 3(驱动实现工程师):根据架构分析结果,
实现 eeprom_driver.c 和 eeprom_driver.h
- Agent 4(测试工程师):同步编写 test_eeprom_driver.c
第三步(依赖第二步结果):
- Agent 5(代码审查员):审查 Agent 3 生成的驱动代码
最后汇总所有 Agent 的结果给我确认。
场景二:系统级问题诊断
提示词(多角度并行排查):
设备在运行 2 小时后出现偶发性 HardFault。请同时启动多个 Agent 从不同角度排查:
Agent A(内存分析师):
分析项目的内存使用情况。检查:
1. FreeRTOS 各任务的栈使用情况(@Core/Src/freertos.c 中的任务栈定义)
2. 全局数组是否有溢出风险
3. heap_4 内存管理方案下是否存在碎片问题
4. 计算 RAM 使用总量,评估 stack/heap 碰撞风险
5. 检查所有 pvPortMalloc 调用是否有对应的 vPortFree
Agent B(中断审查员):
分析所有中断服务程序。检查:
1. @Core/Src/stm32f4xx_it.c 中每个 ISR 的执行时间
2. 是否有 ISR 调用了阻塞函数(HAL_Delay、printf、semaphore take)
3. 中断优先级分配是否合理
4. 是否存在中断嵌套导致的栈溢出
5. DMA 中断和外部中断是否有优先级冲突
Agent C(时序分析师):
分析系统的时序约束。检查:
1. 最高频率的中断是哪个?其最坏执行时间是多少?
2. FreeRTOS Tick 中断是否可能被长时间阻塞
3. 看门狗超时设置是否合理
4. 是否有任务因为低优先级中断过多而被饿死
5. ADC 采样率与数据处理速率是否匹配
三个 Agent 并行执行,结果全部返回后,帮我综合分析可能的根因。
场景三:大规模重构
提示词(设计+影响分析+实施计划):
我们要将项目的 UART 驱动从轮询模式重构为 DMA 模式。
启动多个 Agent 并行工作:
Agent 1(架构分析师)- 设计方案:
1. 读取当前 UART 驱动实现 (@Drivers/uart/uart_driver.c)
2. 设计 DMA 模式的新架构(包括空闲中断接收、DMA 发送完成回调)
3. 定义新旧接口的差异和兼容方案
4. 输出重构设计方案文档
Agent 2(影响分析师)- 评估影响范围:
1. 搜索所有调用 UART 相关函数的代码
2. 列出受影响的模块和文件
3. 评估对其他团队成员的正在开发功能的影响
4. 检查 DMA 资源是否与现有外设冲突
Agent 3(风险分析师)- 评估风险:
1. 分析重构可能引入的 bug 类型
2. 评估回滚方案
3. 列出需要在重构后回归测试的功能点
4. 估算对 RAM/Flash 占用的影响
三个 Agent 并行执行后,汇总结果生成完整的重构计划。
场景四:版本发布前的全面检查
提示词(发布前多维度检查):
准备发布 v2.0.0,启动多个 Agent 同时进行发布前检查:
Agent 1(构建检查):
1. 运行 make clean && make all,确认编译无错误无警告
2. 运行 make unittest,确认所有测试通过
3. 运行 arm-none-eabi-size,对比上一版本的固件大小
4. 检查 .map 文件中是否有异常大的符号
Agent 2(静态分析):
1. 运行 make cppcheck,分析所有警告
2. 检查是否符合 MISRA-C 强制规则
3. 搜索所有 TODO、FIXME、HACK 注释
4. 检查是否有调试代码未清理(被注释的 printf 等)
Agent 3(文档检查):
1. 检查 CHANGELOG.md 是否覆盖了所有变更
2. 检查版本号是否在所有位置已更新(firmware_version.h、Makefile、README)
3. 检查 API 文档是否与代码一致
4. 检查 CLAUDE.md 中的配置是否与实际代码一致
Agent 4(安全检查):
1. 检查是否有硬编码的密钥或密码
2. 检查 JTAG 是否在生产版本中禁用
3. 检查看门狗是否正确配置
4. 检查是否有未处理的编译警告可能隐藏安全问题
所有 Agent 并行执行,汇总后输出发布就绪报告。
场景五:Bug 复现与分析
提示词(多角度分析同一个 bug):
客户报告设备在低温环境(-20°C)下 SPI Flash 写入偶尔失败。
启动多个 Agent 同时分析可能的原因:
Agent A(驱动层分析):
1. 分析 SPI Flash 驱动 (@Drivers/spi/spi_flash.c) 的写入流程
2. 检查页写入时序是否满足芯片规格要求
3. 检查写入完成检测(BUSY 位轮询)的超时设置
4. 检查 CS 片选时序是否正确
5. 分析 DMA 传输是否有缓存一致性问题
Agent B(硬件配置分析):
1. 检查 SPI 时钟频率配置是否过高
2. 检查 GPIO 驱动强度配置
3. 检查 SPI 相关引脚的上拉/下拉电阻配置
4. 分析电源管理相关代码(低功耗模式是否影响 SPI 稳定性)
Agent C(应用层分析):
1. 检查调用 SPI Flash 写入的任务是否存在并发访问
2. 检查是否有其他任务在同一时间操作 SPI 总线
3. 分析写入数据量是否超过页大小对齐要求
4. 检查错误重试机制的实现
综合三个 Agent 的结果,列出可能原因的概率排序和验证方法。
多 Agent 编排提示词模式
模式一:流水线模式(串行依赖)
按顺序执行以下任务,前一个的输出作为后一个的输入:
阶段 1:架构分析师 Agent 分析现有驱动模式
→ 输出:驱动架构模板和规范
阶段 2:驱动实现 Agent 根据模板生成新驱动
→ 输入:阶段 1 的输出
→ 输出:驱动源代码
阶段 3:测试工程师 Agent 为新驱动编写测试
→ 输入:阶段 2 的输出
→ 输出:测试代码
阶段 4:代码审查 Agent 审查驱动和测试
→ 输入:阶段 2 和阶段 3 的输出
→ 输出:审查报告
每完成一个阶段,先让我确认再进入下一阶段。
模式二:并行+汇合模式
并行启动以下 Agent,全部完成后再汇总:
Agent A:分析 @Drivers/SPI/ 的所有源文件,输出 SPI 驱动架构报告
Agent B:分析 @Drivers/I2C/ 的所有源文件,输出 I2C 驱动架构报告
Agent C:分析 @Drivers/UART/ 的所有源文件,输出 UART 驱动架构报告
三个 Agent 全部完成后:
1. 汇总对比三个驱动的架构差异
2. 找出不一致的设计模式
3. 提出统一驱动架构的建议方案
模式三:主从调度模式
你作为主协调者,管理以下工作流:
1. 先启动一个 Agent 分析整个 @Drivers/ 目录,输出所有驱动的文件清单和接口列表
2. 根据分析结果,对每个驱动文件并行启动审查 Agent
3. 收集所有审查结果,按严重程度汇总排序
4. 对 [BLOCK] 级别的问题,启动修复 Agent 逐个修复
5. 最后编译验证所有修复
每一步执行前告诉我你要做什么,等我说"继续"再执行。
模式四:对抗审查模式
启动两个独立 Agent,让它们从不同立场审查同一段代码:
Agent A(实现者视角):
读取 @Drivers/can/can_driver.c,从实现者的角度:
- 解释每个设计决策的原因
- 标注哪些代码是刻意为之(非 bug,是 feature)
- 列出已知的技术债务和权衡取舍
Agent B(审查者视角):
读取 @Drivers/can/can_driver.c,从严格审查者的角度:
- 找出所有可能的 bug 和安全隐患
- 指出代码中的坏味道和反模式
- 建议改进方案
最后汇总两个 Agent 的观点,给出客观的结论。
Agent 提示词编写技巧
技巧一:给 Agent 明确的角色和边界
好的写法:
"你是一位嵌入式安全审查专家。只审查安全相关的问题,
不关注代码风格。输出格式:[严重程度] 文件名:行号 问题描述 修改建议"
差的写法:
"帮我看看这段代码"
技巧二:指定 Agent 可以使用的工具
好的写法:
"使用 Read、Grep、Glob 工具分析代码。
不要修改任何文件,只输出分析报告。"
差的写法:
"分析一下"(可能导致 Agent 尝试修改文件或运行命令)
技巧三:定义清晰的输出格式
好的写法:
"输出格式要求:
# 模块名
| 函数名 | 功能 | 行号 | 问题数 |
|--------|------|------|--------|
最后输出汇总统计。"
差的写法:
"分析完告诉我结果"(输出格式不可控,难以汇总)
技巧四:设置 Agent 的约束条件
好的写法:
"约束条件:
- 不使用动态内存分配(malloc/pvPortMalloc)
- 所有缓冲区使用 static uint8_t 数组
- 中断回调中只允许调用 xSemaphoreGiveFromISR
- 遵循 MISRA-C:2012 强制规则
- 函数不超过 50 行"
差的写法:
"写好一点"(没有具体约束)
技巧五:Agent 间的数据传递
让 Agent A 的输出能被 Agent B 使用:
"阶段 1:启动 Agent 分析 @Middleware/modbus/ 目录,
将分析结果保存到 /tmp/modbus_analysis.md
阶段 2:启动另一个 Agent 读取 /tmp/modbus_analysis.md,
基于分析结果编写测试用例"
多 Agent 协同最佳实践总结
| 实践 | 说明 |
|---|---|
| 先定义 Agent 角色 | 在 .claude/agents/ 中预定义,确保一致性 |
| 明确输入输出 | 每个 Agent 需要知道读取什么、产出什么 |
| 指定可用工具 | 只读分析用 Read/Grep/Glob,需要改代码时才给 Edit/Write |
| 设置约束条件 | 嵌入式项目特别要约束:无 malloc、MISRA-C、栈大小等 |
| 并行无依赖的任务 | 多个独立分析任务并行执行,节省时间 |
| 串行有依赖的任务 | 实现→测试→审查,逐步执行,每步确认 |
| 控制上下文大小 | Agent 做完就返回结果,不要让调查填满主对话 |
| 人工确认关键步骤 | 涉及中断优先级、内存布局等关键修改时,暂停等待确认 |
12. 高级命令与隐藏技巧速查
本章汇总 Claude Code 中不为人知但非常实用的高级命令、快捷键、CLI 参数和技巧,按使用场景分类。
完整斜杠命令速查表
| 命令 | 说明 | 使用场景 |
|---|---|---|
/model |
切换模型(Sonnet/Opus/Haiku) | 复杂分析用 Opus,简单任务切 Sonnet 省钱 |
/cost |
查看当前会话的 token 用量和费用 | 控制预算、评估任务成本 |
/compact |
压缩上下文窗口 | 上下文快满时,保留关键信息 |
/clear |
清空对话历史 | 切换到完全不同的任务 |
/init |
自动生成 CLAUDE.md | 新项目首次使用 |
/config |
打开分页设置界面 | 调整权限、MCP、钩子等配置 |
/doctor |
运行诊断排查问题 | Claude Code 行为异常时 |
/terminal-setup |
配置终端支持 Shift+Enter 多行输入 | 想在终端中输入多行提示词 |
/memory |
浏览和编辑 CLAUDE.md、规则文件、自动记忆 | 管理项目记忆 |
/resume |
交互式选择恢复历史会话 | 继续昨天的工作 |
/rename "名称" |
给当前会话命名 | 方便以后 /resume 查找 |
/hooks |
查看所有已配置的钩子 | 确认钩子是否生效 |
/btw <问题> |
旁路提问,不进入对话历史 | 快速问个无关问题,不浪费上下文 |
/desktop |
将终端会话移交到桌面应用 | 需要可视化 diff 审查 |
/review |
内置代码审查技能 | 快速审查当前变更 |
/commit |
内置智能提交技能 | 自动生成 commit message |
/pr |
内置创建 PR 技能 | 快速创建 Pull Request |
/schedule |
创建定时/周期性任务 | 定时执行代码检查、编译等 |
/loop |
在会话中重复执行提示词 | 轮询式监控(如持续检查编译状态) |
/theme |
切换主题和语法高亮 | 个性化界面 |
/upgrade |
升级订阅计划 | Pro/Max 计划用户 |
嵌入式开发常用命令示例:
/cost # 检查分析 .map 文件花了多少钱
/model sonnet # 切换到 Sonnet 做简单格式化
/model opus # 切换到 Opus 做复杂架构分析
/compact 保留中断优先级分配表和 DMA 通道映射 # 压缩但保留关键硬件配置
/btw STM32F407 的 CAN 波特率计算公式是什么? # 旁路提问不污染主上下文
/rename "CAN驱动开发" # 命名会话,方便以后恢复
隐藏快捷键速查表
| 快捷键 | 说明 | 使用场景 |
|---|---|---|
Esc |
中途停止当前操作 | Claude 走偏了,及时止损 |
Esc + Esc |
回退到之前的检查点 | 恢复到修改前的代码状态 |
Ctrl+C |
取消当前操作 | 彻底中断 |
Ctrl+G 或 Ctrl+X Ctrl+E |
在编辑器中编辑提示词 | 编写长提示词更方便 |
Ctrl+O |
切换执行详情查看器 | 查看 Claude 调用了哪些工具 |
Ctrl+R |
反向搜索历史命令 | 找回之前用过的提示词 |
Ctrl+B |
将运行的命令放到后台 | 编译时间长,不阻塞对话 |
Ctrl+T |
切换任务列表显示 | 查看多任务进度 |
Ctrl+V |
粘贴剪贴板中的图片 | 截图让 Claude 分析波形/电路图 |
Shift+Tab 或 Alt+M |
循环切换权限模式 | 快速在 Auto/Default/Plan 模式间切换 |
Alt+T / Option+T |
切换扩展思考模式 | 复杂推理任务启用深度思考 |
Alt+O / Option+O |
切换快速模式 | 快速迭代时使用 |
Alt+P / Option+P |
切换模型 | 不清空提示词直接换模型 |
Ctrl+X Ctrl+K |
终止所有后台 Agent | Agent 跑飞了,紧急停止 |
\ + Enter |
多行输入 | 所有终端都支持的换行方式 |
! + 命令 |
直接执行 Bash 命令 | 快速执行 !make all 而不需要切换 |
@文件名 |
文件路径自动补全引用 | 快速引用项目文件 |
嵌入式开发快捷键技巧:
# 粘贴示波器截图让 Claude 分析
Ctrl+V → 直接粘贴波形图片 → "分析这个 SPI 时序是否符合规格"
# 粘贴逻辑分析仪截图
Ctrl+V → 粘贴截图 → "检查这个 I2C 通信的 START/STOP/ACK 时序是否正确"
# 在编辑器中编写复杂调试提示词
Ctrl+G → 打开编辑器 → 写好多行提示词 → 保存退出执行
# 快速执行编译
!make all && arm-none-eabi-size build/firmware.elf
# 反向搜索之前用过的调试提示词
Ctrl+R → 输入 "hardfault" → 找到之前的分析提示词复用
高级 CLI 参数速查
会话管理
| 参数 | 说明 | 示例 |
|---|---|---|
--continue, -c |
恢复最近对话 | claude -c |
--resume, -r |
按 ID 或名称恢复 | claude -r "CAN驱动开发" |
--fork-session |
恢复时创建副本(不覆盖原会话) | claude -c --fork-session |
--name, -n |
给会话命名 | claude -n "ADC重构" |
--from-pr <号> |
恢复关联 GitHub PR 的会话 | claude --from-pr 42 |
嵌入式使用示例:
# 继续昨天的 CAN 驱动开发
claude -r "CAN驱动开发"
# 恢复上次的会话但创建分支(保留原始记录)
claude -c --fork-session
# 在 CI 中关联 PR 的代码审查
claude --from-pr 42 -p "审查这个 PR 中涉及的中断优先级变更"
模型与性能控制
| 参数 | 说明 | 示例 |
|---|---|---|
--model |
指定模型 | claude --model opus |
--effort |
思考力度(low/medium/high/max) | claude --effort high -p "分析架构" |
--fallback-model |
主模型过载时自动降级 | claude --model opus --fallback-model sonnet |
嵌入式使用示例:
# 用 Opus 最高力度分析复杂的 HardFault
claude --model opus --effort max -p "分析这个 HardFault 的根因 @crash_log.txt"
# 简单格式化用 Sonnet 快速完成
claude --model sonnet -p "为 Drivers/ 目录下所有 .c 文件添加头文件保护"
# Opus 过载自动降级到 Sonnet
claude --model opus --fallback-model sonnet -p "重构 UART 驱动为 DMA 模式"
系统提示词定制
| 参数 | 说明 |
|---|---|
--system-prompt |
替换整个系统提示词 |
--system-prompt-file |
用文件内容替换系统提示词 |
--append-system-prompt |
追加内容到默认系统提示词 |
--append-system-prompt-file |
追加文件内容到默认系统提示词 |
嵌入式使用示例:
# 追加嵌入式专用系统提示
claude --append-system-prompt "你是一位嵌入式固件开发专家,专注于 STM32 Cortex-M4 平台。
所有代码必须使用静态内存分配,禁止 malloc。
遵循 MISRA-C:2012 规范。使用 HAL 库而非直接操作寄存器。"
# 从文件加载专业系统提示
claude --append-system-prompt-file prompts/embedded_rules.txt
# CI 中使用固定系统提示确保一致性
claude --system-prompt-file prompts/ci_review_prompt.txt \
-p "审查变更" --output-format json
输出与脚本集成
| 参数 | 说明 |
|---|---|
--output-format json |
JSON 格式输出 |
--output-format stream-json |
流式 JSON |
--json-schema |
输出符合指定 JSON Schema |
--max-turns |
限制最大交互轮数 |
--max-budget-usd |
限制花费上限(美元) |
--bare |
极简模式(跳过钩子、技能、MCP、记忆) |
嵌入式 CI/CD 集成示例:
# CI 中结构化代码审查,限制预算和轮数
claude -p "审查 src/ 目录的 MISRA-C 合规性" \
--output-format json \
--max-turns 5 \
--max-budget-usd 1.00 \
--allowedTools Read,Grep,Glob
# 生成符合 Schema 的编译报告
claude -p "分析 .map 文件输出内存报告" \
--output-format json \
--json-schema '{
"type": "object",
"properties": {
"flash_used": {"type": "number"},
"ram_used": {"type": "number"},
"modules": {"type": "array"}
}
}'
# 极简模式快速查询(跳过所有插件和钩子,启动最快)
claude --bare -p "GPIOA 的时钟在 RCC 寄存器中是哪一位?"
Worktree 隔离
| 参数 | 说明 |
|---|---|
--worktree, -w |
在隔离的 git worktree 中工作 |
--tmux |
为 worktree 创建 tmux 会话 |
# 在隔离环境中实验性重构,不影响主分支
claude -w "spi-refactor" -p "将 SPI 驱动从轮询模式重构为 DMA 模式"
# 在 tmux 中并行开发多个功能
claude -w "can-driver" --tmux # 窗口1:CAN 驱动开发
claude -w "adc-driver" --tmux # 窗口2:ADC 驱动开发
# 嵌入式安全实验:隔离环境中修改链接脚本
claude -w "memory-opt" -p "优化 @stm32f407.ld 链接脚本,
将 .bss 段移到 CCM RAM 以释放主 RAM 空间"
权限模式完整说明
通过 Shift+Tab 循环切换或 --permission-mode 指定:
| 模式 | 说明 | 适用场景 |
|---|---|---|
| default | 所有写操作需确认 | 日常开发,最安全 |
| acceptEdits | 自动批准文件编辑和基本文件操作 | 信任 Claude 的代码修改 |
| plan | 只读分析模式,不修改任何文件 | 代码审查、架构分析 |
| auto | AI 分类器自动决定(需 Team/Enterprise/API 计划) | 高效开发,减少中断 |
| dontAsk | 未在白名单中的操作一律拒绝 | CI/CD 中严格限制 |
| bypassPermissions | 跳过所有权限提示(危险) | 完全信任的自动化场景 |
嵌入式开发推荐权限模式:
# 只读分析驱动架构(最安全)
claude --permission-mode plan -p "分析 Drivers/ 的架构模式"
# 日常开发(编辑自动批准,命令需确认)
claude --permission-mode acceptEdits
# CI 中严格模式(只允许白名单操作)
claude --permission-mode dontAsk \
--allowedTools "Read,Grep,Glob,Bash(make cppcheck)" \
-p "运行静态分析"
# 快速原型(完全自动,仅限隔离环境)
claude -w "prototype" --permission-mode auto \
-p "实现一个简单的 GPIO 中断驱动"
记忆系统高级用法
记忆文件优先级(从低到高)
全局策略(管理员设置) # 所有组织用户
~/.claude/CLAUDE.md # 你个人所有项目
./CLAUDE.md 或 .claude/CLAUDE.md # 团队共享(提交到 Git)
./CLAUDE.local.md # 你个人当前项目(加入 .gitignore)
.claude/rules/*.md # 按文件路径匹配的规则
~/.claude/projects/<项目>/memory/MEMORY.md # 自动记忆(每会话自动加载前200行)
路径作用域规则
在 .claude/rules/ 目录下创建 .md 文件,可以针对特定文件模式设置规则:
.claude/rules/drivers.md:
---
paths: ["Drivers/**"]
---
所有驱动代码必须:
- 使用 BSP_ 前缀命名函数
- 包含 init/deinit/read/write/ioctl 五个标准接口
- 错误码使用 drv_errno_t 枚举
- 初始化函数必须检查外设时钟是否已使能
.claude/rules/isr.md:
---
paths: ["**/*_it.c", "**/interrupts/**"]
---
中断服务程序代码必须:
- 禁止调用任何阻塞函数
- 使用 FromISR 版本的 FreeRTOS API
- 共享变量必须使用 volatile 修饰
- 函数末尾必须有中断标志清除操作
CLAUDE.md 中的文件导入
# 主 CLAUDE.md
## 项目约定
见 @docs/coding_style.md 的代码风格说明
## API 规范
见 @docs/api_convention.md
# 最大支持 5 层嵌套导入
自动记忆管理
# 查看和编辑当前项目的记忆
/memory
# 自动记忆保存在这里(跨会话持久化)
~/.claude/projects/<项目路径>/memory/MEMORY.md
# 禁用自动记忆(如 CI 环境)
CLAUDE_CODE_DISABLE_AUTO_MEMORY=1 claude -p "查询"
让 Claude 记住嵌入式项目的关键信息:
记住以下信息,以后在这个项目中都要遵循:
- 当前 STM32F407 的 DMA1 已被 SPI2 占用,新驱动请使用 DMA2
- CAN1 和 CAN2 共享滤波器RAM,配置时需要先初始化 CAN1
- FreeRTOS 的 tick 频率是 1000Hz,configTICK_RATE_HZ = 1000
- 串口调试输出使用 UART1(PA9/PA10),不要改其他串口
钩子系统完整事件列表
| 事件 | 触发时机 | 典型用途 |
|---|---|---|
SessionStart / SessionEnd |
会话开始/结束 | 环境初始化、资源清理 |
UserPromptSubmit |
用户提交提示词 | 注入上下文、预处理 |
PreToolUse |
工具执行前 | 阻止危险操作、注入参数 |
PostToolUse |
工具执行后 | 自动格式化、记录日志 |
Notification |
Claude 发送通知 | 自定义通知方式 |
SubagentStart / SubagentStop |
子代理启停 | 监控 Agent 行为 |
PreCompact / PostCompact |
上下文压缩前后 | 保留关键信息 |
Stop |
Claude 完成响应 | 触发后续自动化 |
钩子处理器类型:
command:执行 Shell 命令http:POST 到指定 URLprompt:单轮 LLM 判断(是/否)agent:启动子代理验证条件
嵌入式钩子高级配置示例:
{
"hooks": {
"PreToolUse": [{
"type": "command",
"command": "check_tool Safety",
"matcher": "Bash",
"run": "per_call"
}],
"PostToolUse": [{
"type": "command",
"command": "clang-format -i -style=file {file}",
"matcher": "Edit",
"run": "per_call"
}],
"SessionStart": [{
"type": "command",
"command": "echo '会话开始于 $(date)' >> .claude/session_log.txt"
}],
"Stop": [{
"type": "command",
"command": "make cppcheck 2>&1 >> .claude/check_log.txt",
"run": "per_call"
}]
}
}
远程控制与多设备协作
# 在 claude.ai 网页端启动一个远程会话
claude --remote "分析这个嵌入式项目的代码质量"
# 将网页端会话拉取到本地终端执行
claude --teleport
# 启用远程控制(从 claude.ai 或手机 App 控制终端)
claude --remote-control
# 桌面应用调度:从手机发任务,桌面自动创建会话执行
# 设置方法:Claude Desktop App → 设置 → 启用 Dispatch
嵌入式远程协作场景:
场景:你在办公室用电脑开发,回家后想用手机检查编译状态
1. 办公室电脑启动 Claude Code 并启用远程控制:
claude --remote-control -n "固件编译监控"
2. 回家后用手机打开 claude.ai,连接到该会话
3. 在手机上发送指令:
"运行 make all && arm-none-eabi-size build/firmware.elf,告诉我编译结果和固件大小"
4. 结果返回手机,无需打开电脑
定时任务与循环执行
# 创建定时任务(云端执行,电脑关机也能跑)
/schedule
# 在会话中循环执行(轮询式监控)
/loop 每 30 秒检查一次编译状态
嵌入式定时任务示例:
# 每天凌晨自动执行代码质量检查
/schedule
每天凌晨 2:00 执行以下任务:
1. git pull origin develop
2. make clean && make all
3. make cppcheck
4. make unittest
5. arm-none-eabi-size build/firmware.elf
6. 将结果发送到团队的飞书/钉钉群
# 循环监控编译输出
/loop 每 10 秒检查 make all 的编译进度
管道与脚本集成进阶
# 粘贴图片 + 提示词组合
claude -p "分析这张电路图中的 SPI 接线是否正确" < circuit_screenshot.png
# 编译错误自动修复循环
make all 2>&1 | claude -p "分析编译错误并自动修复,修复后重新编译" --max-turns 10
# 批量文件处理
for f in Drivers/**/*.c; do
claude -p "为 $f 添加 Doxygen 注释,不修改函数实现" \
--allowedTools Edit,Read \
--permission-mode auto
done
# 从文件读取提示词(复杂场景)
cat > /tmp/review_prompt.txt << 'EOF'
审查当前 git diff 中的所有变更,重点检查:
1. 中断优先级是否有变更
2. DMA 通道是否冲突
3. FreeRTOS 任务栈大小是否调整
输出结构化的审查报告。
EOF
claude -p "$(cat /tmp/review_prompt.txt)" --output-format json
Vim 编辑模式
在 /config → 编辑器模式中选择 Vim,即可在提示词编辑中使用 Vim 操作:
| 操作 | 按键 |
|---|---|
| 进入插入模式 | i, I, a, A, o, O |
| 移动 | h/j/k/l, w, e, b, 0, $, gg, G |
| 删除 | x, dd, D, dw, cc, C, cw |
| 复制粘贴 | yy, yw, p, P |
| 缩进 | >>, << |
| 重复 | . |
| 文本对象 | iw/aw, i"/a", i(/a(, i[/a[ |
环境变量速查
| 变量 | 说明 | 示例 |
|---|---|---|
ANTHROPIC_API_KEY |
API 密钥(bare 模式认证) | CI 环境中使用 |
CLAUDE_CODE_DISABLE_AUTO_MEMORY |
禁用自动记忆 | =1 |
CLAUDE_CODE_NEW_INIT |
启用交互式多阶段 /init | =1 |
CLAUDE_CODE_DISABLE_BACKGROUND_TASKS |
禁用后台 Bash | =1 |
CLAUDE_CODE_TASK_LIST_ID |
跨会话共享任务列表 | 用命名目录标识 |
嵌入式 CI 环境配置示例:
# Jenkins/GitLab CI 中的环境变量设置
export ANTHROPIC_API_KEY="sk-xxx" # API 密钥
export CLAUDE_CODE_DISABLE_AUTO_MEMORY=1 # CI 中不需要记忆
export CLAUDE_CODE_NEW_INIT=0 # 不需要交互式 init
# 执行自动审查
claude -p "审查本次提交的代码变更" \
--bare \
--max-turns 3 \
--max-budget-usd 0.50 \
--output-format json
PR 状态可视化
当你在有开放 PR 的分支上工作时,Claude Code 底部会显示 PR 状态:
| 颜色 | 状态 |
|---|---|
| 绿色 | Approved |
| 黄色 | Pending review |
| 红色 | Changes requested |
| 灰色 | Draft |
| 紫色 | Merged |
Ctrl+点击/Cmd+点击在浏览器中打开 PR- 每 60 秒自动刷新状态
- 需要安装并认证
ghCLI
高级技巧汇总
技巧一:图片分析(截屏调试)
# 截取示波器/逻辑分析仪屏幕
# 在 Claude Code 中按 Ctrl+V 粘贴
"分析这个 SPI 通信波形:
- CLK 频率是否符合配置的 10MHz?
- MOSI 数据是否与预期一致(应发送 0xAA 0x55)?
- CS 片选时序是否正确(传输期间应保持低电平)?"
技巧二:预算控制
# 限制单次任务花费不超过 2 美元
claude -p "全面审查项目代码" --max-budget-usd 2.00
# 限制最多 5 轮交互
claude -p "修复编译错误" --max-turns 5
技巧三:Bare 极简模式
# 最快启动,跳过所有插件和钩子
claude --bare -p "解释这段汇编代码的含义"
技巧四:多工作目录
# 同时加载多个目录(如固件项目 + 共享驱动库)
claude --add-dir /path/to/shared_drivers -p "对比两个项目的 SPI 驱动实现差异"
技巧五:JSON Schema 强制输出
# 强制输出符合 Schema 的结构化数据
claude -p "列出所有外设驱动的 API" \
--output-format json \
--json-schema '{
"type": "array",
"items": {
"type": "object",
"properties": {
"module": {"type": "string"},
"functions": {"type": "array", "items": {"type": "string"}},
"file": {"type": "string"}
}
}
}'
技巧六:后台编译不阻塞
# 在 Claude Code 对话中
请运行 make all 并将编译放到后台
(Claude 会用 Ctrl+B 放到后台,编译完成后通知你)
编译期间我可以继续问你其他问题
技巧七:会话分支
# 从历史会话分叉出新会话(不影响原会话)
claude -c --fork-session
# 适用场景:在一个会话中完成了驱动开发
# 想基于同一上下文开始做代码审查,但不想污染原始开发记录
技巧八:Agent Teams(多 Claude 实例协作)
# 启动多个 Claude 实例作为团队协作
# 在 tmux 中显示多个 Agent 的实时状态
claude --teammate-mode tmux -p "同时实现 CAN 和 UART 驱动"
# Agent 之间可以共享任务和通信
# 适合大规模并行开发
功能速查决策树
你的需求是什么?
│
├─ 快速提问/查资料 ──→ /btw 问题
├─ 切换模型 ────────→ /model 或 Alt+P
├─ 看花了多少钱 ────→ /cost
├─ 上下文快满了 ────→ /compact 或 /clear
├─ Claude 走偏了 ───→ Esc 停止 → Esc+Esc 回退
├─ 代码审查 ────────→ /review 或 plan 模式
├─ 提交代码 ────────→ /commit
├─ 创建 PR ─────────→ /pr
├─ 定时任务 ────────→ /schedule
├─ 循环监控 ────────→ /loop
├─ 多行输入 ────────→ \ + Enter 或 Ctrl+G
├─ 粘贴图片 ────────→ Ctrl+V
├─ 隔离实验 ────────→ --worktree
├─ CI 自动化 ───────→ --bare -p --max-budget-usd --max-turns
├─ 远程控制 ────────→ --remote-control
├─ 跨会话记忆 ──────→ /memory 或 CLAUDE.md
└─ 诊断问题 ────────→ /doctor
13. 常见问题与排错
Q: Claude 的回答偏离了方向怎么办?
按 Esc 停止,然后 Esc+Esc 回退到之前的检查点,重新描述需求。
Q: 上下文快满了但任务还没完成?
使用 /compact 保留关键信息 压缩对话历史,或者 /clear 重新开始。
Q: Claude 总是反复犯同一个错误?
不要反复纠正超过 2 次。/clear 后重写提示词,提供更清晰的指令和验证标准。
Q: 如何让 Claude 记住项目约定?
在项目根目录创建 CLAUDE.md,使用 /init 可以自动生成初始版本。
Q: 如何减少权限确认弹窗?
- 使用
Shift+Tab切换到 Auto 模式 - 在
.claude/settings.json中配置权限白名单 - 对可信命令使用
--permission-mode auto启动
Q: Claude 执行太慢?
- 使用
/fast切换快速模式 - 提示词更精确,减少不必要的探索
- 使用子代理处理调查任务,避免填满主上下文
Q: 嵌入式项目中 MCP Server 连接失败?
- 检查 MCP Server 的命令路径是否正确(绝对路径更可靠)
- 确认 Python/Node.js 环境已安装且版本兼容
- 查看
.claude/settings.json中的mcpServers配置格式 - 使用
claude mcp list查看已注册的 MCP 服务器状态 - 查看 Claude Code 的日志输出(
--verbose模式)定位具体错误
Q: 如何让 Claude 帮我分析硬件调试器的输出?
- 将 GDB、OpenOCD、串口日志等输出重定向到文件
- 使用
@文件名引用日志文件让 Claude 分析 - 或通过管道直接传入:
cat debug_log.txt | claude -p "分析这段调试日志"
Q: 如何在团队中统一 Claude Code 的配置?
- 将
CLAUDE.md和.claude/settings.json提交到 Git 仓库 - 将
.claude/settings.local.json加入.gitignore(个人配置) - 团队约定统一的代码格式化配置(
.clang-format) - 团队约定统一的静态分析配置(
.clang-tidy、cppcheck 配置) - 在 README 中记录 Claude Code 的使用约定和常用技能
Q: 如何处理第三方库代码不被 Claude 修改?
- 在 CLAUDE.md 中明确标注第三方库目录(如
CMSIS/、Middlewares/Third_Party/) - 在权限配置中排除第三方目录的编辑权限
- 使用
.claudeignore文件排除不需要 Claude 访问的目录
基于 Claude Code 官方文档整理
更多推荐



所有评论(0)