1. 为什么我想给嵌入式开发配几个“数字同事”
做嵌入式这行十几年,我最大的感受不是技术更新快,而是开发流程太碎。一个项目从需求到量产,中间要经过硬件选型、原理图评审、驱动移植、RTOS 配置、协议栈调试、功耗测试、EMC 整改、产线工装、固件升级方案设计……每一块都够一个人啃半年。更麻烦的是,这些环节之间信息传递全靠人脑和零散文档,一个参数改错,后面可能连炸三块板子。
最近两年 AI Agent 这个概念火得不行,但大部分讨论都集中在 Web 后端、数据分析、客服机器人这些纯软件场景。嵌入式圈子聊 AI,多半是“端侧推理”“TinyML”“NPU 加速”这类把 AI 塞进设备的方向。很少有人反过来想:能不能让 AI Agent 来辅助嵌入式工程师本身的工作?
我花了大概四个月时间,基于开源框架搭了一套自己的 AI Agent 工作流,内部叫它“五个数字同事”。它们分别覆盖需求拆解与选型、原理图与硬件检查、驱动与 BSP 移植、RTOS 与中间件配置、测试与量产工装这五个环节。不是那种“帮你写两行代码”的玩具,而是能真正接任务、查资料、出报告、给建议的 Agent 组合。
这套东西适合谁?如果你是一个人扛一个项目的嵌入式老兵,或者小团队里既要画板又要写驱动还要管产线的“全栈嵌入式”,那这套思路能帮你省下大量重复劳动。如果你刚入行,还在看嵌入式学习路线、刷嵌入式八股文,那也可以把它当成一个加速理解开发流程的辅助工具——前提是你自己得先懂基本原理,不然 Agent 给你的东西你根本判断不了对错。
下面我把整个搭建思路、每个 Agent 的职责边界、实际跑起来的流程、踩过的坑,全部拆开讲。代码和配置我会给关键片段,但重点在为什么这么设计,因为工具会变,逻辑不会变。
2. 五个数字同事的整体架构与分工逻辑
2.1 为什么是五个而不是一个万能 Agent
一开始我也想过搞一个“超级嵌入式 AI”,什么都能问。实测下来效果很差:上下文太长,它会把硬件问题和驱动问题混在一起回答;工具调用太杂,查数据手册和查 RTOS 配置的 API 完全不是一回事;最要命的是责任边界模糊,它给你的建议你没法判断该信哪部分。
后来我参考了嵌入式开发本身的阶段划分,把整个流程切成五段,每段配一个独立 Agent,各自有专属的工具集、知识库和输出格式。它们之间通过一个任务总线传递结构化数据,比如硬件 Agent 输出的引脚分配表,会直接变成驱动 Agent 的输入约束。
这五个 Agent 的分工是这样的:
| Agent 代号 | 覆盖阶段 | 核心职责 | 主要工具 |
|---|---|---|---|
| 选型助手 | 需求与选型 | 拆解需求、对比芯片、生成选型报告 | 芯片数据库、参数对比脚本、价格查询接口 |
| 硬件哨兵 | 原理图与 PCB | 检查引脚冲突、电源域、信号完整性规则 | 网表解析器、规则引擎、数据手册检索 |
| 驱动工匠 | 驱动与 BSP | 生成驱动框架、移植 BSP、配置设备树 | 内核源码索引、设备树模板、编译验证 |
| 系统管家 | RTOS 与中间件 | 配置任务优先级、堆栈、协议栈参数 | RTOS 配置解析、协议栈文档库、静态分析 |
| 产线教头 | 测试与量产 | 生成测试用例、工装脚本、烧录方案 | 测试框架模板、工装 API、日志分析 |
每个 Agent 都是一个独立的 LangGraph 节点,可以单独调用,也可以串成流水线。我用的框架是FastAPI + LangChain + LangGraph,模型侧混用本地部署的小模型和云端 API,敏感数据走本地,通用知识走云端。
2.2 任务总线怎么设计才不混乱
五个 Agent 如果各干各的,最后就是五份互不相关的报告,没法用。我设计了一个轻量的任务总线,本质是一个 JSON 格式的上下文对象,在 Agent 之间流转。它包含几个关键字段:
{ "project_id": "xxx", "stage": "driver", "constraints": { "mcu": "STM32H743", "clock": "480MHz", "pin_assignments": {...}, "power_domains": {...} }, "artifacts": { "selection_report": "...", "schematic_check": "...", "driver_code": "..." }, "open_issues": [...] }这个总线的好处是:每个 Agent 只读自己需要的字段,只写自己负责的字段。硬件哨兵不会去改驱动代码,驱动工匠也不会去动选型报告。如果发现上游给的约束有问题,就写入open_issues,由我人工裁决后再往下走。
注意:任务总线一定要有版本号。我踩过的坑是,硬件改了引脚分配,驱动 Agent 还在用旧数据,结果生成的设备树引脚全错。后来加了
constraints_version,每次硬件变更就递增,驱动 Agent 发现版本不匹配就拒绝执行。
2.3 本地模型和云端模型怎么分工
嵌入式开发涉及大量芯片手册、原理图、内部协议,这些数据不能随便往外传。我的策略是:
- 本地跑一个小参数模型(7B 级别),负责代码生成、格式转换、简单规则检查。
- 云端 API 负责复杂推理,比如选型对比、架构方案评估,但输入前会做脱敏,只传通用参数,不传具体项目名和网络拓扑。
- 向量数据库放本地,存数据手册、应用笔记、历史项目文档,用嵌入模型做检索。
实测下来,本地模型在驱动代码生成上够用,但在“为什么这个电源方案不行”这种需要跨领域推理的问题上,还是得靠大模型。所以我的 Agent 里有一个路由层,根据任务类型决定走本地还是云端。
3. 选型助手:从模糊需求到可执行选型报告
3.1 需求拆解不是让 AI 瞎猜
嵌入式项目最怕需求模糊。客户说“要一个低功耗的控制器,带无线,成本要低”,这句话里全是坑。低功耗是多久待机?无线是 Wi-Fi 还是 BLE 还是 LoRa?成本低是 BOM 成本还是整体方案成本?
选型助手的第一步不是查芯片,而是把模糊需求拆成可量化指标。我给它预设了一套提问模板,基于常见嵌入式项目的维度:
- 供电方式:电池 / 适配器 / PoE
- 待机功耗目标:uA 级 / mA 级
- 无线协议:BLE / Wi-Fi / LoRa / Zigbee / 4G
- 算力需求:Cortex-M0+ / M4 / M7 / A 系列
- 温度等级:消费级 / 工业级 / 车规级
- 封装约束:QFN / BGA / LQFP
- 成本区间:单芯片价格上限
- 开发生态:是否有现成 SDK、社区活跃度
Agent 会把这些维度做成一个交互式问卷,我填完之后它才进入检索阶段。这一步看似麻烦,但比后面选错芯片重新画板省太多时间。
3.2 芯片对比的数据从哪来
选型最花时间的是查数据手册、对比参数。我的做法是:
- 先用爬虫把主流厂商的公开选型表抓下来,存进本地数据库。
- 对每个候选芯片,用嵌入模型检索数据手册关键页,提取功耗、外设、封装、价格区间。
- 生成对比表格,并标注数据来源和置信度。
对比表大概长这样:
| 型号 | 内核 | 主频 | 待机电流 | 无线 | 封装 | 参考单价 | 生态评分 |
|---|---|---|---|---|---|---|---|
| STM32WLE5 | M4 | 48MHz | 1.2uA | LoRa | QFN48 | $4.5 | 高 |
| nRF52840 | M4 | 64MHz | 1.5uA | BLE | QFN48 | $5.2 | 高 |
| ESP32-C3 | RISC-V | 160MHz | 5uA | Wi-Fi/BLE | QFN32 | $1.8 | 中 |
提示:价格字段一定要标注“参考价”和获取日期。芯片价格波动大,Agent 给的历史价格只能做相对比较,不能直接写进 BOM。
3.3 选型报告的输出格式
选型助手最后输出的不是一段文字,而是一个结构化报告,包含:
- 需求摘要(我填的问卷)
- 候选芯片对比表
- 推荐方案及理由
- 风险提示(比如某芯片交期长、某封装焊接难度高)
- 下一步行动建议(需要确认的引脚、需要申请的样片)
这个报告会直接写入任务总线的artifacts.selection_report,硬件哨兵和驱动工匠都会读它。实测下来,原来需要两三天查资料对比的选型工作,现在半天就能出一版可讨论的报告。
4. 硬件哨兵:原理图检查与引脚冲突排查
4.1 网表解析是硬件 Agent 的基础
硬件 Agent 要干活,首先得“看懂”原理图。我用的方案是:从 EDA 工具导出网表文件(Netlist),然后用 Python 脚本解析成结构化数据。网表里包含元件、引脚、网络连接关系,这是后续所有检查的基础。
解析完之后,Agent 可以做几类检查:
- 引脚冲突:同一个 MCU 引脚被分配给两个外设。
- 电源域检查:3.3V 器件和 1.8V 器件直连。
- 上拉下拉缺失:I2C 总线没有上拉电阻。
- 晶振负载电容:与数据手册推荐值偏差过大。
- 复位电路:复位引脚没有 RC 或专用复位芯片。
这些规则一部分是硬编码的规则引擎,一部分是让 Agent 查数据手册后动态判断。比如晶振负载电容,不同芯片要求不一样,必须查手册。
4.2 引脚分配表的自动生成与校验
嵌入式开发里,引脚分配是个容易出错又费时的活。我让硬件哨兵根据选型报告和原理图网表,自动生成一张引脚分配表:
| 引脚 | 功能 | 外设 | 方向 | 备注 |
|---|---|---|---|---|
| PA0 | USART2_TX | 串口 | 输出 | 调试口 |
| PA1 | USART2_RX | 串口 | 输入 | 调试口 |
| PB6 | I2C1_SCL | 传感器 | 双向 | 需上拉 |
| PB7 | I2C1_SDA | 传感器 | 双向 | 需上拉 |
| PC13 | GPIO | LED | 输出 | 低电平点亮 |
这张表会写入任务总线,驱动工匠直接用它生成设备树或初始化代码。如果硬件改了引脚,版本号递增,驱动 Agent 会收到通知。
注意:Agent 生成的引脚表一定要人工复核一遍。我遇到过 Agent 把调试串口引脚分配给了 PWM 输出,原因是它没识别出“调试口”这个约束。后来我在规则里加了“调试口优先级最高”的硬约束。
4.3 硬件检查的常见误报与处理
硬件哨兵跑久了,会发现它经常误报。比如:
- 误报一:I2C 上拉电阻在另一页原理图上,网表解析没跨页关联。
- 误报二:某些引脚在芯片内部已有上拉,外部不需要再加。
- 误报三:电源域检查没考虑电平转换芯片。
处理办法是给每条规则加一个白名单机制,我确认过的误报就加入白名单,下次不再报。同时 Agent 会记录误报原因,定期让我 review,避免规则越来越松。
5. 驱动工匠:BSP 移植与设备树生成
5.1 驱动代码生成的边界在哪
驱动工匠是我用得最多的 Agent,但也是最需要小心用的。它擅长的是:
- 根据引脚分配表生成 GPIO 初始化代码。
- 根据外设配置生成 I2C、SPI、UART 的初始化结构体。
- 根据设备树模板生成 DTS 节点。
- 根据 RTOS 配置生成任务框架。
它不擅长的是:
- 复杂的时序控制(比如某些传感器的上电时序)。
- 中断优先级和临界区保护。
- DMA 与 Cache 一致性处理。
所以我的用法是:让 Agent 生成 70% 的样板代码,我手工补 30% 的关键逻辑。这样效率最高,风险也可控。
5.2 设备树生成的实操流程
以嵌入式 Linux 项目为例,设备树是 BSP 移植的核心。驱动工匠的流程是:
- 读取任务总线里的引脚分配和外设信息。
- 检索内核源码里的同类设备树节点作为模板。
- 生成 DTS 片段,并标注哪些字段需要人工确认。
- 调用交叉编译工具链做语法检查。
- 输出 diff 和检查报告。
生成的 DTS 片段大概这样:
&i2c1 { status = "okay"; clock-frequency = <400000>; pinctrl-0 = <&i2c1_pins>; pinctrl-names = "default"; sensor@48 { compatible = "ti,tmp102"; reg = <0x48>; interrupt-parent = <&gpio1>; interrupts = <12 IRQ_TYPE_EDGE_FALLING>; }; };提示:Agent 生成的设备树一定要用
dtc编译一遍,再上板测试。我遇到过 Agent 把clock-frequency写成clock_frequency,编译不报错但驱动跑不起来,查了半天。
5.3 驱动调试的日志分析辅助
驱动跑不起来的时候,Agent 可以帮忙分析内核日志。我把dmesg输出丢给它,让它做几件事:
- 提取与目标驱动相关的行。
- 匹配常见错误模式(probe failed、timeout、resource busy)。
- 给出可能原因和排查步骤。
这个功能在调试 I2C 和 SPI 设备时特别有用,因为内核日志往往很长,人工筛选费时。Agent 能快速定位到关键错误行,并给出“先查供电、再查地址、再查时序”的排查顺序。
6. 系统管家:RTOS 配置与中间件参数调优
6.1 任务优先级和堆栈的自动检查
RTOS 项目里,任务优先级配错、堆栈给太小,是常见的死机原因。系统管家会读取 RTOS 配置文件(比如 FreeRTOS 的FreeRTOSConfig.h和任务创建代码),做几类检查:
- 优先级是否有重复且未使用时间片。
- 高优先级任务是否有阻塞操作。
- 堆栈大小是否与任务内局部变量匹配。
- 中断优先级与 RTOS 可管理优先级是否冲突。
它输出的是一张风险表:
| 任务 | 优先级 | 堆栈 | 风险 | 建议 |
|---|---|---|---|---|
| comm | 5 | 512 | 堆栈偏小 | 建议 1024 |
| sensor | 3 | 1024 | 正常 | 保持 |
| led | 1 | 256 | 正常 | 保持 |
6.2 协议栈参数配置的辅助
嵌入式项目常用协议栈:lwIP、MQTT、Modbus、CANopen。这些协议栈的参数配置文档往往很厚,系统管家可以:
- 根据应用场景推荐参数(比如 MQTT 的 keepalive、lwIP 的 TCP 窗口)。
- 检查参数之间是否矛盾。
- 生成配置说明文档。
比如 lwIP 的TCP_SND_BUF和TCP_WND如果配得太小,吞吐量上不去;配得太大,内存不够。Agent 会根据可用 RAM 和网络场景给出建议区间。
6.3 静态分析与代码规范检查
系统管家还集成了静态分析工具(比如cppcheck、clang-tidy),对驱动和中间件代码做检查。Agent 会把工具输出翻译成人话,并给出修复建议。比如:
cppcheck报“数组越界风险”,Agent 会定位到具体行,并解释为什么可能越界。clang-tidy报“未初始化变量”,Agent 会建议初始化位置。
这个功能在代码 review 时特别省事,尤其是团队里新人写的代码。
7. 产线教头:测试用例与工装脚本生成
7.1 测试用例的自动生成逻辑
产线测试是嵌入式项目最后一道关,也是最容易被忽视的环节。产线教头会根据硬件设计和驱动配置,自动生成测试用例框架:
- GPIO 测试:遍历所有可控 GPIO,输出高低电平并回读。
- 通信测试:UART 回环、I2C 扫描、SPI 读写 ID。
- 存储测试:Flash 擦写、EEPROM 读写。
- 传感器测试:读取 ID 寄存器、检查数据范围。
- 功耗测试:不同模式下的电流测量点。
这些用例会生成 Python 脚本或 C 测试代码,配合工装夹具使用。
7.2 工装脚本与烧录方案
产线教头还能生成烧录和工装控制脚本。比如:
import serial import time def flash_device(port, firmware): ser = serial.Serial(port, 115200, timeout=5) ser.write(b'flash\n') time.sleep(0.5) with open(firmware, 'rb') as f: ser.write(f.read()) response = ser.readline() if b'OK' not in response: raise RuntimeError('Flash failed') ser.close()注意:工装脚本一定要加超时和重试。产线环境干扰大,串口通信偶尔失败很正常,没有重试机制会导致误判。
7.3 测试日志的自动分析与报告
产线跑完测试后,日志往往是一大堆文本。产线教头会:
- 提取每个测试项的通过/失败状态。
- 统计失败率最高的测试项。
- 关联失败项与硬件设计(比如某个 GPIO 测试总失败,可能是焊接问题)。
- 生成产线报告,标注需要人工复检的板子。
这个功能在小批量试产阶段特别有用,能快速发现设计或工艺问题。
8. 实际跑起来的完整流程与踩坑记录
8.1 从需求到样机的 Agent 流水线
我把五个 Agent 串成一条流水线,实际跑一个项目的流程是这样的:
- 我输入模糊需求,选型助手交互式提问,输出选型报告。
- 我确认选型后,硬件哨兵读取报告,生成引脚分配表和原理图检查清单。
- 硬件工程师画完原理图,导出网表,硬件哨兵做检查,输出问题列表。
- 我修复硬件问题后,驱动工匠读取引脚表,生成驱动框架和设备树。
- 系统管家检查 RTOS 配置和协议栈参数。
- 产线教头生成测试用例和工装脚本。
- 样机出来后,跑测试,日志回传给产线教头分析。
整个流程里,我的角色从“什么都自己干”变成“审核和决策”。Agent 负责生成和检查,我负责判断和拍板。
8.2 踩过的坑:Agent 不是万能的
坑一:Agent 会编造数据手册参数。早期我没做检索增强,直接问模型“STM32H743 的待机电流是多少”,它给了一个看起来很合理的数字,但和手册对不上。后来强制所有参数必须来自本地向量库检索,并标注页码。
坑二:上下文太长导致遗忘。项目大了之后,任务总线里的 artifacts 越来越多,Agent 开始“忘记”前面的约束。解决办法是每个 Agent 只加载自己需要的字段,并且定期做上下文压缩。
坑三:工具调用失败没有降级方案。有一次编译工具链路径变了,驱动工匠调用编译失败,整个流程卡住。后来加了降级逻辑:编译失败就跳过验证,输出代码并标注“未验证”。
坑四:Agent 生成的代码风格不统一。五个 Agent 各写各的,变量命名、注释风格都不一样。后来加了一个统一的代码规范配置文件,所有 Agent 生成代码前先读规范。
8.3 常见问题速查表
| 问题 | 可能原因 | 排查步骤 | 解决 |
|---|---|---|---|
| Agent 不响应 | 模型服务挂了 | 检查本地模型进程和 API 连通性 | 重启服务或切换备用模型 |
| 生成代码编译失败 | 工具链路径错 | 检查环境变量和 Makefile | 修正路径,重新生成 |
| 引脚冲突误报 | 网表跨页未关联 | 检查网表导出设置 | 合并网表或加白名单 |
| 设备树不生效 | 字段名拼写错 | 用 dtc 编译并对比手册 | 修正字段名 |
| 测试用例漏项 | 硬件设计变更未同步 | 检查任务总线版本号 | 重新生成测试用例 |
9. 这套东西到底省了多少时间
我拿最近一个工业传感器项目做了对比。传统流程下,选型加硬件评审大概 3 天,驱动框架加设备树 2 天,RTOS 配置和协议栈调试 2 天,测试用例和工装脚本 1.5 天,总共约 8.5 人天。用这套 Agent 流水线之后,选型半天,硬件检查半天,驱动生成加人工补全 1 天,RTOS 配置半天,测试用例半天,总共约 3 人天。省下来的时间主要是在查资料、写样板代码、做重复检查上,真正需要人判断的架构设计和疑难调试,时间没怎么变。
但我要说清楚:这套东西的前提是你自己得懂嵌入式。Agent 给你的选型报告,你得能看出哪个参数有问题;Agent 生成的驱动代码,你得能判断哪里需要加临界区保护;Agent 给的测试用例,你得知道哪些项必须人工复检。如果你自己不懂,Agent 只会让你错得更快。
另外,这套架构不是固定的。你可以只搭一个驱动工匠,也可以把五个都搭起来。关键是任务总线的设计和每个 Agent 的职责边界要清晰。我见过有人把五个 Agent 做成一个超级 Agent,结果就是什么都干不好。
最后分享一个我最近在试的扩展方向:把产线教头的日志分析结果反哺给硬件哨兵和驱动工匠,形成闭环。比如产线发现某个 GPIO 测试失败率高,硬件哨兵下次检查时就会重点关注这个引脚的焊接和上拉配置。这个闭环还在调,等跑稳了再单独写一篇。