ARTICLE DETAIL

资讯详情

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

嵌入式开发中的AI工作流:从代码生成到硬件闭环调试

嵌入式开发中的AI工作流:从代码生成到硬件闭环调试 嵌入式软件工程师的工作流和纯后端工程师有一个显著差异代码写完并不代表任务结束后面还有交叉编译、板级烧录、波形核对、寄存器调试这一整套硬件闭环。越是老手越会把大量时间花在阅读芯片手册、翻内核源码、比对寄存器定义和排查编译链接问题上而不是单纯写代码。AI 进入这个领域之后最大的价值不是替工程师把驱动写完而是把“查资料、理解上下文、生成初稿、定位问题”这些分散环节串成一条可复用、可保存、可复盘的工作流。本文面向正在开发嵌入式 Linux 或单片机项目的工程师也适合刚入门想用 AI 提速学习路线的开发者。文章不讨论训练模型也不讨论端侧推理部署只讨论一件事在现有 AI 工具能力内如何把它们嵌入嵌入式软件开发的日常节奏。读完你会有几条可落地的提示词模板、一套排错思路以及一版适合团队内部沉淀的 AI 工作流清单。1. 嵌入式场景里的 AI 能做什么不能做什么1.1 为什么嵌入式工作流比 Web 开发更需要 AI嵌入式开发和互联网应用开发看起来都是写代码但上下文差距很大。Web 开发里一个接口出错本地起服务、查日志、看监控链路基本能定位。嵌入式项目则往往碰到的是“代码编译过了烧进去不跑”“寄存器读出来不对”“中断没进”“板子莫名死机”这类需要通过硬件手段反复定位的问题。这类问题有一个共同点知识分散。芯片参考手册几百上千页寄存器位段描述用词严谨但冗长内核源码里的驱动框架层层封装一个函数调用栈可能跨三个子系统工具链的链接脚本、启动文件、编译选项又各自有一套规则。工程师大量时间花在“把分散信息组织到一起”上。AI 恰恰擅长做信息压缩、上下文拼接和初稿生成所以嵌入式开发非常适合用它来搭建工作流。另一个原因是嵌入式代码的“不可直接验证性”。后端代码改完能单测嵌入式驱动多半要看硬件表现。AI 生成的代码可能 90% 正确但剩下的 10% 恰好卡在寄存器地址、时序参数或编译器字节对齐上。这种情况下工程师的价值不是从零写代码而是快速判断 AI 输出哪里有问题并给出修正方向。这个判断力正是嵌入式 AI 工作流的核心。1.2 AI 在嵌入式开发里真正有用的六类场景结合日常开发经验下面六类场景最容易见效。每一类都有明确的输入和验证方式。场景输入材料AI 输出验证方式芯片手册解读寄存器位段描述、章节摘录结构化说明、初始化顺序对照硬件实测驱动框架生成MCU 型号、外设要求、接口约束驱动骨架代码交叉编译 板级验证编译链接报错定位错误日志、构建命令、工程结构根因分析和修改建议重新编译观察错误是否消失源码阅读辅助内核函数、调用链、源码片段逻辑流程图、调用关系、关键路径对照源码逐行核实测试用例生成纯逻辑函数、接口定义单元测试代码、边界用例在宿主机或目标板运行测试文档与注释维护旧代码、变更记录注释、设计文档、提交说明团队评审这里最核心的规律是AI 适合处理“信息密集型”任务不适合处理“物理验证密集型”任务。手册解读、报错定位、代码初稿都属于信息密集而时序测量、信号完整性、功耗测试这些必须靠仪器和板子完成。1.3 暂时不适合交给 AI 的部分有几个方向不建议让 AI 直接负责。第一是中断上下文和实时性敏感代码比如中断服务函数里的临界区保护、信号量释放时机、内存屏障位置。这些逻辑的难点不在语法而在于对硬件行为和系统实时性的理解AI 没有执行环境无法验证。第二是安全认证相关的代码例如功能安全项目中需要追溯需求到代码到测试用例的环节。AI 生成的内容无法提供符合认证要求的追溯链路只能作为参考。第三是板级硬件问题。AI 无法替你确认某个引脚有没有虚焊、电源纹波是否过大、晶振是否起振。它能把故障可能性排序但最终判断必须靠示波器、万用表和逻辑分析仪。注意给 AI 设定边界不是限制使用而是避免把时间浪费在它天然不擅长的任务上同时防止 AI 输出在硬件环境里产生误导。2. 环境准备从 IDE 插件到本地模型按成本选级别2.1 三类 AI 工具形态嵌入式工程师选择 AI 工具时通常遇到三种形态。第一种是 IDE 或编辑器里的代码助手代表是 Cursor、Continue 插件一类直接在代码上下文里补全和问答。它们适合生成代码、解释函数、改 bug但对硬件环境的理解依赖你提供的信息。第二种是通用对话式大模型适合做手册解读、知识问答、方案设计。它的优势是没有 IDE 束缚粘贴寄存器描述、报错日志、源码片段都能处理。缺点是上下文有限复杂工程需要分块喂。第三种是本地私有化部署。很多嵌入式项目处于内网环境代码不能上传到外部 AI 服务。这时可以在开发机或服务器上部署量化模型配合本地知识库做检索增强生成。成本在 GPU、内存、运维和模型调优上适合团队长期使用。形态优点约束适合场景IDE 代码助手与代码编辑融合效率高需要网络或企业代理代码可能外发日常编码、代码补全、函数解释对话式大模型信息吞吐大支持片段粘贴上下文有限、外部服务约束手册解读、方案设计、排错讨论本地私有化部署数据不出内网可控性强硬件资源要求高、维护成本大保密项目、离线开发环境如果项目对代码保密要求高优先确认代码外发边界。很多 IT 部门会限制代码上传权限这时候本地模型是更稳妥的选择。如果是个人学习或开源项目在线代码助手的效率更高。2.2 嵌入式开发环境的联合准备AI 工具只是工作流的一部分完整的嵌入式开发验证环境仍然不能少。下面这些工具需要提前备齐。# 交叉编译器示例 arm-none-eabi-gcc --version aarch64-linux-gnu-gcc --version # 下载调试工具 openocd --version st-flash --version交叉编译器负责把代码编译成目标平台可执行文件。调试下载工具负责把镜像写入开发板。AI 生成代码后最终都要回到命令行编译和下载。只有这些工具链稳定AI 工作流才有闭环。还需要准备一个最简单的可运行工程作为“基线工程”。这个工程能完成点灯或串口打印编译链、链接脚本、启动文件都已验证。AI 生成的新代码在这个基线上叠加可以快速区分问题是出在新代码还是出在工程配置上。实际项目里这一步经常被跳过导致 AI 生成的驱动无法编译误以为是代码写错实际是工程结构不匹配。2.3 给 AI 喂信息的基本格式很多嵌入式工程师问 AI 得不到好答案问题不在 AI而在输入信息太少。直接问“给 STM32 写一个 I2C 驱动”AI 只能给泛化模板。要得到可落地代码需要提供四类信息。第一硬件信息。包括 MCU 型号、外设实例、引脚复用关系、时钟频率。第二工程信息。包括编译工具链、IDE 或构建系统、芯片型号宏定义、链接脚本位置。第三业务要求。包括驱动要完成什么功能、性能要求、内存限制、实时性约束。第四验证条件。包括期望用什么方式验证比如串口打印、寄存器回读、逻辑分析仪抓波形。我在嵌入式 Linux 项目中使用 STM32MP157需要写一个 I2C 主机驱动来读取板载温度传感器。 硬件接线I2C2 SCLPH4SDAPH5传感器地址 0x48。 工具链arm-none-eabi-gcc 10.3使用 STM32CubeMX 生成的工程。 已使能 I2C2 时钟GPIO 复用已配置。 请生成 1. 寄存器初始化函数时钟 100kHz。 2. 单字节读写函数包含超时处理。 3. 验证方式建议优先用寄存器回读。 注意不可以使用现成 HAL 库基于寄存器操作。这种提示词的优点是明确告诉 AI“不可以使用现成 HAL 库”避免它生成一套依赖你根本没有的软件包。工作中也可以反过来明确要求“必须使用某版本 SDK 的接口”让 AI 在指定框架内输出。3. “先分解需求再生成代码”用 AI 跑通一个外设驱动3.1 需求拆解是第一环新手使用 AI 生成代码时通常直接要完整代码。经验丰富一点的工程师会让 AI 先做需求拆解形成清单后再逐项生成。这一步很关键因为 AI 一次输出的大段代码往往耦合度过高出问题时难以定位。以外设驱动为例需求拆解可以写出下面这样的清单AI 完全能根据你要实现的外设类型生成并检查清单完整性。请把“编写 I2C EEPROM 24C02 驱动”拆成开发任务清单。 每个任务包含接口函数、依赖条件、验证方式、是否可在宿主机测试。 重点拆分初始化、单字节写、页写、随机读、顺序读、写保护处理。AI 输出清单后逐项确认是否符合需求。例如页写要考虑 EEPROM 页边界跨页问题随机读需要先发设备地址还是先发内存地址这些细节可以再次追问 AI。需求拆解的价值在于把一个大任务变成可以逐项验证的小任务每完成一项就可以编译一次、烧录一次问题会提前暴露。3.2 基于寄存器生成驱动框架下面用一段基于寄存器的 I2C 初始化代码示例展示 AI 生成结果的形态和注意点。这里的寄存器名仅用于说明思路实际项目必须根据芯片手册替换。#include platform_i2c_regs.h typedef struct { volatile uint32_t CR1; volatile uint32_t CR2; volatile uint32_t OAR1; volatile uint32_t DR; volatile uint32_t SR1; volatile uint32_t SR2; } i2c_regs_t; #define I2C2_BASE ((i2c_regs_t *)0x40005800UL) #define I2C_CR1_PE (1U 0) #define I2C_CR1_START (1U 8) #define I2C_CR1_STOP (1U 9) #define I2C_CR1_ACK (1U 10) #define I2C_CR1_SWRST (1U 15) #define I2C_CR2_FREQ_MASK (0x3FU 0) #define I2C_CR2_ITBUFEN (1U 10) #define I2C_CR2_ITEVTEN (1U 9) #define I2C_CR2_ITERREN (1U 8) static void i2c2_enable_clock(void) { // 开启 GPIO 时钟和 I2C2 时钟 // 具体 RCC 寄存器位因芯片而异这里仅保留调用入口 } static void i2c2_init_pin_mux(void) { // 将 PH4/PH5 复用为 I2C2 功能 // 需要根据数据手册配置 AF 编号和开漏、上拉属性 } int i2c2_init(uint32_t bus_freq_hz) { uint32_t pclk1 54000000UL; uint32_t freq_mhz pclk1 / 1000000UL; i2c2_enable_clock(); i2c2_init_pin_mux(); regs-CR1 | I2C_CR1_SWRST; regs-CR1 ~I2C_CR1_SWRST; regs-CR2 ~I2C_CR2_FREQ_MASK; regs-CR2 | (freq_mhz I2C_CR2_FREQ_MASK); regs-CR2 | I2C_CR2_ITBUFEN | I2C_CR2_ITEVTEN | I2C_CR2_ITERREN; // CCR、TRISE 配置需要结合芯片手册 // 100kHz 模式的 CCR 计算与 APB 时钟有关 regs-CR1 | I2C_CR1_PE; return 0; }这段代码的关键点是AI 可以生成寄存器操作的骨架但时钟频率计算、引脚复用编号、RCC 位段必须对照手册确认。比如 CCR 计算不同 I2C 模式下公式不同快速模式还要关注 DUTY 位。直接让 AI 生成很可能会给出一个近似的寄存器值但如果你不告诉它准确的 APB 时钟频率和模式它只能猜。推荐做法是先把芯片手册对应章节和寄存器描述粘贴给 AI再让它生成代码。例如把“I2C_CR1 的 PE 位在第 0 位SWRST 在第 15 位”这类信息喂给 AI生成结果会更准确。3.3 编译、烧录和验证代码生成后回到工程编译。下面是一个简化 Makefile 示例。CROSS_COMPILE ? arm-none-eabi- CC : $(CROSS_COMPILE)gcc OBJCOPY : $(CROSS_COMPILE)objcopy MCU : cortex-m7 CFLAGS : -mcpu$(MCU) -mthumb -g -Wall -O2 -I./inc LDFLAGS : -Tlink.ld SRCS : main.c i2c2_driver.c syscalls.c OBJS : $(SRCS:.c.o) TARGET : app.elf all: $(TARGET) $(OBJCOPY) -O binary $(TARGET) app.bin $(TARGET): $(OBJS) $(CC) $(LDFLAGS) -o $ $(OBJS) %.o: %.c $(CC) $(CFLAGS) -c -o $ $ clean: rm -f $(OBJS) $(TARGET) app.bin flash: openocd -f interface/stlink.cfg -f target/stm32mp15x.cfg -c program app.bin 0x00000000 verify reset exit编译成功后下载到板子。验证方式建议分三档先看寄存器是否初始化成功再读回外设状态寄存器然后通过 API 发出操作命令用逻辑分析仪抓引脚波形最后接上真实设备验证数据正确性。make clean make make flash如果编译失败复制完整错误日志给 AI同时附上工程目录结构。比直接问“为什么编译失败”有效得多。错误日志要包含错误类型、文件名、行号、报错信息三行以上上下文。4. 让 AI 帮你读内核源码而不是替你写全部代码4.1 带着问题读源码让 AI 输出调用链嵌入式 Linux 开发中阅读内核源码是高频工作。比如排查一个 I2C 总线上的设备驱动 probe 不执行的问题需要理解设备树、I2C 核心、驱动模型之间的关联。这类跨层级的调用链AI 很擅长串联。一个可行的提示词模板是把函数名、文件路径、依赖关系告诉 AI让它输出完整调用流程。我在阅读 Linux 内核源码版本 5.15。 文件drivers/i2c/i2c-core-base.c 函数i2c_register_adapter 问题请说明从 i2c_add_adapter 到 i2c_register_adapter 的完整调用路径 以及设备树节点匹配 i2c 设备时of_i2c_register_devices 的作用。 输出格式调用路径 每步关键函数作用 可能失败点。AI 返回结果后你仍然需要回到源码逐段确认。它的价值是给了你一张地图地图上有几处地标省去从零开始翻书的时间。特别是在分析 platform 设备、i2c 设备和驱动匹配关系时给出具体函数名能显著减少搜索路径。4.2 把数据手册变成结构化表格对付几百页的芯片手册AI 可以把零散的位段描述整理成表格。例如打开 UART 章节把寄存器地址、位段名称、位偏移、复位值、读写属性、描述原文摘录进对话让 AI 输出结构化速查表。下面是芯片手册中 UART_MCR 寄存器的位段描述片段 位 7:6 保留。 位 5 UART_MCR_AFCE 自动流控使能。 位 4 UART_MCR_LOOP 回环模式。 位 3 保留。 位 2 UART_MCR_OUT1。 位 1 UART_MCR_OUT2。 位 0 UART_MCR_DTR 数据终端就绪。 请整理成表格字段位段名称、位偏移、复位值、读写属性、典型场景说明。输出表格后建议和手册核对一遍。寄存器位段描述通常没有歧义但 AI 可能因为截断或理解偏差漏掉某些保留位。整理后的表格可以存入项目笔记后续让 AI 生成测试代码时直接引用。4.3 代码审查场景AI 也能作为代码审查的初筛工具。把一段函数体、结构体定义、调用约定、平台约束发给 AI让它从空指针、未初始化、类型溢出、字节序、并发访问和防御性编程几个角度检查。static int sensor_read_reg(struct sensor_dev *dev, uint8_t reg, uint8_t *buf) { uint8_t tmp; if (dev NULL || buf NULL) { return -1; } tmp reg; return i2c_transfer(dev-i2c_client, tmp, 1, buf, 1); }请审查上面这段代码。重点检查 1. 参数为空时的处理是否合理。 2. 是否有缓冲区溢出风险。 3. i2c_transfer 返回值的处理是否严谨。 4. 是否存在并发访问或中断上下文调用风险。 只列出可能的问题和修改建议不要重写整个文件。这种审查只是初筛。AI 可以发现逻辑缺失但硬件时序、总线占用时间、调用频率这类信息它并不知道。最终审查结论仍由有经验的工程师确认。比较实用的做法是把 AI 审查意见作为评审会议前的预读材料提高评审效率。5. 排错工作流把日志、报错和现象组合起来给 AI5.1 编译和链接错误排查嵌入式工程编译报错常见关键词是 undefined reference、section overflow、region FLASH overflowed 这类。给 AI 的信息必须包含三部分完整报错日志、构建命令、工程中与内存分配相关的配置。错误关键词常见根因检查方向undefined reference源文件未加入构建、依赖库缺失、符号命名不匹配检查 Makefile 或 CMakeLists 中源文件列表、链接库region FLASH overflowed镜像超过芯片 Flash 容量查看链接脚本、优化编译选项、裁剪代码或数据region RAM overflowed堆栈或全局数据超出 RAM检查大数组、栈大小、链接脚本内存布局multiple definition函数或全局变量在多个源文件定义检查头文件中的变量定义、重复 include 的静态变量cannot find -lxxx指定链接库不存在或路径缺失检查库文件安装位置和链接参数 -L提示词模板编译报错如下 arm-none-eabi-gcc -Tlink.ld -o app.elf main.o i2c.o /usr/bin/ld: app.elf section .text will not fit in region FLASH /usr/bin/ld: region FLASH overflowed by 4120 bytes 工程使用 STM32F103C8T6Flash 64KB。 请问怎么定位是哪些段占用过多在不改芯片的情况下有哪些处理手段AI 会给出查看 map 文件、优化等级、合并字符串常量等建议。实际排查时打开编译生成的 .map 文件按占用大小排序。5.2 硬件初始化不生效的排查链路驱动代码编译烧录后板子没有按预期工作这是嵌入式开发最耗时的问题。排查顺序建议是电和时钟、引脚复用、外设寄存器、中断、业务逻辑。AI 能帮你生成检查清单但测量动作必须靠人。下面是一份适合给 AI 补充信息的现象描述格式。开发板某 Cortex-M4 板卡 现象I2C EEPROM 读返回全 0xFF 已确认时钟已使能、引脚复用已配置、I2C 初始化函数返回 0 已做用逻辑分析仪抓 SCL没有看到时钟信号 请给出下一步排查顺序和每步的验证方法。AI 可能给出的建议包括检查 GPIO 是否开漏、是否接了上拉电阻、I2C 是否处于总线忙状态、SCL 引脚是否复用到正确 AF、外设时钟是否真正写入寄存器。把这些问题整理成表格逐项排查效率会高很多。5.3 问题描述模板把模糊现象变成可处理问题“板子不工作”是无效描述。换成下面的模板无论问 AI 还是请教同事都能更快得到有效答案。硬件平台MCU 型号开发板型号关键外设 软件环境工具链版本SDK 版本工程结构 复现步骤做了哪些操作 期望行为希望出现什么现象 实际现象实际出现什么现象包括日志、波形、寄存器值 已尝试措施做过哪些变更和验证 约束条件内存限制、实时性要求、功耗要求这个模板同样适用于工作流记录。每次排错后把描述、结论和修复方式保存到团队知识库。积累几个月后相同类型的问题可以直接检索历史记录节省重复定位时间。6. 常见误区与常见坑6.1 三个典型误区误区一让 AI 直接生成整个产品级驱动。很多驱动涉及时序、中断、并发、功耗管理AI 缺少运行环境生成的代码只能作为初稿。正确做法是把驱动拆成初始化、读写、中断、低功耗等小模块逐个生成、逐个验证。误区二只问一次不迭代。AI 对话适合持续追问。第一次得到模板后继续补充硬件细节、报错信息、测试结果让 AI 根据新信息修正。比如第一次生成 I2C 初始化后告诉它“我的 APB1 时钟是 54MHz总线频率要求 400kHz”它会重新计算 CCR 值。误区三把 AI 输出当权威不查手册。AI 训练数据里大量代码来自公开项目不一定适配你的芯片版本。寄存器偏移、位段名、复位值都可能存在差异。所有关键硬件信息必须以芯片手册为准。6.2 常见坑速查表坑现象原因对策寄存器位段写错外设功能不生效寄存器读回异常芯片版本不同或手册理解错误对照具体型号手册核对位段字节序不一致SPI/I2C 通信数据错乱主从设备字节序配置不同明确 MSB/LSB 顺序查看数据手册忙等超时缺失外设未响应时程序卡死轮询状态位缺少超时机制给所有 while 等待加超时计数编译优化导致延时不准软件延时时间不符合预期高优化等级下循环被优化使用定时器或 DWT 计数器链接脚本内存越界烧录成功但程序跑飞堆栈或数据段超出 RAM查 map 文件调整内存布局使能时钟遗漏外设寄存器写不进总线时钟未打开初始化前先确认 RCC 对应位这六个坑在 AI 生成代码里经常出现尤其是前两个。AI 生成外设驱动时倾向于使用通用寄存器名实际芯片可能已经改名或改位。所以代码生成后的第一件事不是烧录而是逐个核对寄存器宏定义和手册。6.3 避免把“AI 能问答”当成“AI 能运行”对话式 AI 只能根据你的描述推理它无法感知板子状态。比如你问“为什么中断没有触发”AI 会列出几十种可能但它不知道你的 NVIC 是否使能、引脚是否配置成中断模式、中断标志是否清除。这些都需要你在提示词里主动说明或者先自己查一轮再问。实际项目里我会把这套流程写成固定的“排错首发包”日志、寄存器转储、原理图关键部分、已经排除的项。每次排错先运行一条命令导出这些信息再粘贴给 AI比一句一句问高效得多。7. 嵌入式 AI 工作流的可复用清单7.1 让 AI 生成代码前的检查清单下面是每次让 AI 写代码前的内部检查清单建议保存为团队文档。是否已提供 MCU 型号、芯片系列、工具链版本。是否已说明工程结构或构建系统。是否已明确外设和引脚分配。是否已指定使用 HAL、LL 库还是寄存器操作。是否已告诉 AI 可用的接口约束和禁止事项。是否已定义验证方式编译、烧录、逻辑分析仪还是寄存器回读。是否已声明内存、实时性、功耗限制。是否预留了人工审查步骤。清单的目的不是增加负担而是减少来回沟通。信息越完整AI 输出越接近可用状态。哪怕只提供其中四项也比直接扔一句“帮我写个 GPIO 驱动”有效。7.2 日常沉淀的提示词模板库建议在使用中逐步积累自己的模板库下面几类在嵌入式场景里最常用。手册解读模板 下面是某芯片寄存器描述章节请整理成结构化说明并标出初始化时需要注意的位段顺序。 【粘贴手册原文】 报错定位模板 以下是我的编译/运行日志。请先定位错误类型再给出从日志提取到的关键信息最后给出排查步骤。 【粘贴日志】 源码分析模板 函数 X 在文件 Y 中。请画出它的调用链说明入参、返回值、出错分支以及它依赖的外部资源。 【粘贴源码】 代码审查模板 请审查以下代码只输出问题列表和修改建议不要重写全部代码。重点检查空指针、溢出、并发、边界条件。 【粘贴代码】 现象描述模板 硬件平台【填写】软件环境【填写】复现步骤【填写】期望行为【填写】实际现象【填写】已尝试措施【填写】。这套模板和 Web 端常见的工作流编码工具、低代码编排思路不太一样。嵌入式场景里代码助手、对话问答、CLI 验证三者组合起来的效率通常比搭建复杂的可视化工作流更直接。7.3 团队落地建议如果团队想要推进 AI 工作流不建议一上来就要求所有人使用统一工具。更好的方式是让一两位熟悉 AI 的工程师先在真实项目里跑通“生成代码 交叉编译 板级验证 沉淀模板”的闭环把案例整理成文档再逐步推广。保密要求高的项目优先考虑本地部署或私有化接入方式。这里不只是模型本身还包括提示词、代码片段、日志在内的敏感信息处理策略。团队应明确哪些数据可以传递给外部服务哪些必须留在内网。对于刚入门的开发者最有价值的练习不是让 AI 写一个大项目而是从一个小驱动开始按“让 AI 解释手册生成最小代码编译下载观察波形修正问题”的路径重复几次。这个循环会让你理解 AI 输出和硬件现实之间的差距也会形成自己的判断标准。等积累一定经验后AI 工作流的收益会远超单点节省的时间。
返回列表