场景与目标
嵌入式开发琐碎且重复:查寄存器手册、抄初始化模板、逐位调试协议解析。这一篇我们用 Codex CLI 辅助完成一个真实的 STM32F103C8T6 项目:LED 闪烁 + 串口命令解析 + DHT11 温湿度采集,重点看 AI 在每个环节能帮到什么、哪里必须人工把关。
第一步:写好 AGENTS.md,让 AI 了解你的工程
在工程根目录创建 AGENTS.md(Codex 每次启动自动读取):
# 工程:stm32-dht11(STM32F103C8T6)
- 构建:STM32CubeIDE 工程,HAL 库版本 1.8.5
- 烧录:ST-Link + OpenOCD,脚本 flash.sh
- 引脚:LED=PA5,DHT11=PB0,调试串口=USART1(PA9/PA10,115200)
- 约定:
- 中断服务函数中只置标志位,业务逻辑放主循环
- 外设句柄统一在 main.c 顶部定义
- 新增外设时同步更新 README.md 的引脚表
这份约定文件是 AI 输出质量的关键——引脚、库版本、编码规范写得越清楚,生成的代码越接近可直接编译。
第二步:生成外设初始化代码
直接向 Codex 下需求:
codex "基于当前 HAL 工程生成 USART1 驱动模块 usart.c/usart.h:
1. 115200-8-N-1,使能接收中断
2. 提供 usart_send_string() 与 printf 重定向
3. 中断里只写入环形缓冲区,主循环提供 usart_read_line() 取整行"
Codex 会读取工程中已有的 CubeMX 生成代码,保持一致的命名与结构,输出可编译的驱动模块。你只需要确认:中断优先级分组是否与现有工程一致、缓冲区大小是否合理。
第三步:协议解析——AI 最擅长的部分
串口命令解析是典型的"规则明确但细节多"的活,交给 Codex:
codex "在命令解析模块中支持以下指令:
- LED ON / LED OFF 控制 PA5
- TEMP 读取并回传 DHT11 数据,格式:TEMP:25,HUMI:60
- 未知命令回传 ERR:UNKNOWN
使用状态机实现,函数加注释,并补一个纯逻辑的测试文件(不依赖硬件)"
把协议逻辑与硬件解耦(纯状态机 + 依赖注入的收发接口),AI 生成的代码甚至可以带一套 PC 上就能跑的单元测试——这在传统嵌入式开发里经常被省掉。
第四步:代码审查与重构
让 Codex 以"审查者"身份通读你的改动:
codex "审查本次未提交的改动(git diff):
1. 检查中断安全:是否有在 ISR 中调用非可重入函数
2. 检查 volatile:中断与主循环共享的变量是否正确声明
3. 检查 DHT11 时序延时的精度假设是否可靠
输出问题清单,按严重程度排序,先不要改代码"
实测中它对中断安全、volatile 缺失、缓冲区边界这类问题命中率很高;而时序类问题(如 DHT11 的微秒级延时依赖具体主频)它只能给出提示,仍需你用示波器/逻辑分析仪确认。
第五步:读手册、写文档
- 把数据手册相关章节(或你的笔记)放进项目,让 Codex 对照解释寄存器配置
- 每次功能完成后执行:~~~codex "更新 README:补充本模块的用法、引脚与已知限制"~~~,文档不再欠账
必须人工把关的清单
| 项目 | 原因 |
|---|---|
| 中断时序与优先级 | 依赖硬件拓扑,AI 无法感知 |
| volatile / 原子性 | AI 常漏报跨文件共享场景 |
| 微秒级延时精度 | 与主频、编译器优化相关 |
| 电源、时钟树、Boot 配置 | 涉及具体板卡设计 |
| HAL 库版本差异 | API 行为可能随版本变化 |
小结
Codex 在嵌入式开发中的正确打开方式是:让它写"规则明确"的代码,人来把关"依赖硬件"的部分。配合 AGENTS.md 固化工程约定,初始化模板、协议解析、单元测试、文档维护这些占开发量大头的琐事,效率至少提升一倍。若你在国内网络环境,可配合 API 中转站使用,具体配置见本站的《Codex 结合 API 中转站使用教程》。