ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

ISP、ICP、IAP烧录方式全解析:从研发到量产的核心区别与实战指南

ISP、ICP、IAP烧录方式全解析:从研发到量产的核心区别与实战指南 芯片烧录这个词很多刚入行的朋友第一次听到会以为是某种焊接工艺或者觉得是把程序写进芯片这么简单的一句话就能带过。但真正做过量产的人都知道烧录环节出问题轻则一批板子返工重则整条产线停线。而 ISP、ICP、IAP 这三个缩写几乎贯穿了从研发打样到量产维护的全过程偏偏很多教程把它们混在一起讲导致新手越看越糊涂。我做过几年嵌入式开发和产线支持踩过不少烧录相关的坑这篇文章就把这三个概念彻底拆开讲清楚它们各自解决什么问题、在什么场景下用、实际操作中又有哪些容易忽略的细节。不管你是刚接触单片机的新手还是需要对接产线的工程师看完应该都能理清思路。1. 先把烧录这件事的本质说透1.1 芯片为什么需要烧录这步要理解 ISP、ICP、IAP得先明白烧录到底在干什么。我们写的代码经过编译之后变成一堆二进制数据这些数据必须被放进芯片内部的非易失性存储器里芯片上电后才能按照我们的逻辑运行。这个把二进制数据放进芯片存储区的过程就是烧录。这里有个关键点芯片出厂时它的 Flash 或 ROM 是空的或者只有厂商预置的引导程序。空白的芯片不会执行任何用户逻辑所以必须有人把程序灌进去。早期的一次性可编程芯片OTP烧录一次就锁死写错了整颗芯片报废那种痛现在很多新手已经体会不到了。现在的芯片大多用 Flash 工艺可以反复擦写烧录方式也演化出了多种路径这才有了 ISP、ICP、IAP 的分工。你可以把芯片想象成一台刚出厂的电脑硬盘是空的。烧录就是给这台电脑装操作系统。装系统的方式有好几种可以用 U 盘引导装、可以拆下硬盘接到别的机器上装、也可以在系统已经跑起来之后在线升级。ISP、ICP、IAP 对应的正是这几种不同的装系统思路。1.2 三个缩写的字面含义与核心差异先把三个词的字面意思摆出来后面再逐个展开ISPIn-System Programming在系统编程。芯片已经焊在板子上了通过预留的接口比如 SWD、JTAG、UART、SPI直接对它烧录。ICPIn-Circuit Programming在电路编程。这个和 ISP 经常被混用严格来说 ICP 强调的是通过电路上的调试接口对芯片操作很多厂商把 ICP 和 ISP 当作同义词。IAPIn-Application Programming在应用编程。芯片里已经跑着一段程序通常是 Bootloader由这段程序自己去擦写另一块存储区实现自我更新。三者的核心差异在于谁来执行烧录动作以及芯片处于什么状态。ISP/ICP 是外部工具主动往芯片里写芯片此时基本是被动挨写的状态IAP 是芯片自己运行的程序在写自己外部只负责把新固件传进来。对比维度ISPICPIAP全称In-System ProgrammingIn-Circuit ProgrammingIn-Application Programming执行者外部烧录器外部烧录器芯片内 Bootloader芯片状态复位/停止运行复位/停止运行正常运行中典型接口SWD/JTAG/UART/SPI调试接口任意通信接口主要场景研发调试、量产量产、在线测试现场升级、OTA是否需要拆焊否否否这张表建议先记住后面每一节我都会结合具体操作再讲一遍因为光看定义很容易以为自己懂了一上手就懵。2. ISP 在系统编程研发阶段最常用的烧录方式2.1 ISP 的工作机制与接口选择ISP 的核心思路是芯片已经焊在 PCB 上了我不拆它直接用板子上引出的调试接口把程序写进去。这个接口通常是芯片厂商规定的比如 ARM Cortex-M 系列芯片普遍支持 SWDSerial Wire Debug两线接口只需要 SWCLK 和 SWDIO 两根线加上电源和地四根线就能烧录。为什么 ISP 这么受欢迎因为它对产线太友好了。想象一下如果每颗芯片都要先烧录再焊接那贴片厂就得额外配置烧录工位芯片还要经历一次烧录-搬运-贴片的流程效率和良率都受影响。ISP 让烧录可以放在焊接之后做甚至可以在整机装配完成后做灵活性高得多。接口选择上有几个实际考量。SWD 占用引脚少适合引脚紧张的板子JTAG 功能更全能调试多核、能做边界扫描但占用 4-5 根线UART 烧录成本最低很多低成本方案用串口配合芯片内置的 Bootloader 实现 ISP但速度慢、可靠性依赖时序。我个人的经验是研发阶段优先用 SWD因为配合调试器可以单步、断点、看寄存器排查问题方便量产阶段如果成本敏感可以考虑 UART 方案。2.2 用 ST-Link 给 STM32 烧录的完整流程拿最常见的 STM32 举例讲一遍 ISP 的实操。你需要一块 ST-Link 调试器、目标板、以及 STM32CubeProgrammer 这个官方工具。接线是这样的ST-Link 的 SWCLK 接目标板 SWCLKSWDIO 接 SWDIOGND 接 GND3.3V 接目标板供电如果目标板自己供电就不要接避免电源冲突。这里有个新手常犯的错误把 ST-Link 的 3.3V 和目标板的外部电源同时接上导致两个电源打架轻则烧录不稳定重则损坏调试器。正确做法是二选一要么调试器供电要么目标板自己供电。接好线之后打开 STM32CubeProgrammer选择 ST-LINK 模式点击 Connect。如果连不上先检查这几点目标板是否上电、SWD 引脚是否被程序复用成了普通 IO、芯片是否处于低功耗模式导致调试接口关闭。最后这一点特别坑很多芯片进入 Stop 或 Standby 模式后 SWD 会失效需要先复位或者用 BOOT 引脚强制进入系统存储器启动模式才能重新连上。连接成功后加载编译好的 hex 或 bin 文件点击 Download 就能烧录。烧录完成后建议勾选 Verify让工具读回数据做校验避免写入过程中出现位翻转却没被发现。2.3 ISP 烧录中那些文档不会写的坑说几个我实际踩过的坑。第一个是复位电路的影响。有些板子的复位引脚上挂了大电容导致调试器发出的复位信号被延迟烧录时好时坏。解决办法是缩短复位走线、减小电容或者在烧录时把调试器设成软件复位模式。第二个是时钟配置。如果芯片的程序把外部晶振配置错了导致主频跑飞调试接口可能连不上。这时候需要用调试器的Connect under reset功能在芯片复位释放的瞬间抢占连接。第三个是读保护。芯片如果开了读保护RDPISP 连接会被拒绝必须先解除保护而解除保护通常会触发全片擦除。量产时如果误开了读保护又没记录返工就很麻烦。所以量产前一定要确认保护等级并且把解锁流程写进作业指导书。提示ISP 烧录前务必确认目标板的供电状态和调试接口是否被程序占用这两个原因能解释八成的连不上问题。3. ICP 在电路编程和 ISP 到底差在哪3.1 ICP 与 ISP 的边界其实很模糊很多资料把 ICP 和 ISP 当成一回事这不算错但也不完全对。从字面看ISP 强调在系统里ICP 强调在电路里两者都是不拆芯片直接烧。区别更多是历史习惯和厂商用词一些老牌厂商尤其是早期单片机厂商习惯用 ICP 来描述通过调试接口烧录而 ARM 生态更常用 ISP。真正值得区分的是烧录接口的性质。ICP 通常特指通过芯片原生的调试接口Debug Interface进行编程这个接口是芯片设计时就固化好的独立于用户程序。而 ISP 的范围更宽既包括调试接口也包括通过 UART、SPI、CAN 等通信接口配合内置 Bootloader 的方式。换句话说ICP 是 ISP 的一个子集。理解这个区别的实际意义在于当你用调试接口烧录时无论程序怎么写、有没有跑飞只要芯片没坏、调试接口没被永久关闭你都能连上而当你用通信接口做 ISP 时依赖的是芯片里预置的 Bootloader一旦 Bootloader 被擦除或者被用户程序覆盖这条路就断了。3.2 量产场景下 ICP 的工装设计量产用 ICP 烧录核心是工装。你不能指望工人拿着调试器一根根插线效率太低还容易接错。常见的做法是做一套烧录治具用探针Pogo Pin对准板子上的测试点压下去就完成电气连接然后批量烧录。治具设计有几个要点。测试点的位置要避开高元件否则探针压不到测试点要留够面积一般直径不小于 1mm太小了探针接触不良电源和地要多留几个测试点保证大电流烧录时压降小。我见过一个项目治具只留了一个 GND 测试点结果烧录时电流稍大就导致接触电阻上的压降让芯片复位烧录成功率只有七成后来加了三个 GND 点才稳定。烧录顺序也有讲究。量产通常采用先贴片后烧录但如果板子上有多个需要烧录的芯片比如主控加一颗无线模块就要考虑烧录顺序和接口复用。有些方案会让主控先烧录再由主控通过 SPI 给无线模块烧录这样只需要一个对外接口治具更简单。3.3 离线烧录器与在线烧录的取舍量产烧录分在线和离线两种。在线烧录是治具连着电脑由上位机软件控制离线烧录是把固件预先存进烧录器烧录器脱机工作工人按一下按钮就烧一片。在线烧录的优点是灵活换固件方便能实时记录烧录日志缺点是依赖电脑电脑死机、USB 掉线都会影响产线。离线烧录的优点是稳定、速度快、不占电脑适合大批量缺点是换固件要重新灌烧录器版本管理容易乱。我的建议是小批量、多品种用在线大批量、单一品种用离线。如果产线规模大可以考虑离线烧录器 集中管理软件的方案烧录器联网从服务器拉取固件既稳定又能统一管理版本。4. IAP 在应用编程让芯片自己给自己升级4.1 IAP 的存储分区设计IAP 是三个概念里最高级的因为它要求芯片自己运行的程序去改写自己的存储区。这里有个物理限制芯片不能一边执行 Flash 里的代码一边擦写同一块 Flash因为擦写期间那块存储区是不可读的。所以 IAP 必须做分区。典型的分区方案是把 Flash 分成三块Bootloader 区、Application 区、以及可选的备份/升级区。Bootloader 是芯片上电后最先运行的程序它负责判断是否需要升级、把新固件从升级区搬运到 Application 区、然后跳转过去执行。Application 就是我们的业务程序它运行时如果收到升级指令就把新固件写到升级区然后复位让 Bootloader 去处理。分区大小要提前规划好。Bootloader 一般占几 KB 到几十 KB取决于功能复杂度Application 区要留够业务代码增长的空间升级区至少要能放下一个完整的 Application 镜像。如果 Flash 紧张可以用乒乓方案即两个 Application 区交替使用但这样 Flash 占用翻倍。4.2 Bootloader 跳转的关键细节Bootloader 跳转到 Application 这段代码是 IAP 最容易出问题的地方。核心步骤是关闭所有中断、设置栈指针MSP为 Application 的向量表首地址、设置跳转地址为 Application 的复位向量、然后执行跳转。这里有个经典问题Application 里定义的变量在跳转后会怎样。答案是全局变量和静态变量在跳转后是未初始化的因为启动代码startup还没跑.data 段还没从 Flash 拷贝到 RAM.bss 段还没清零。所以 Application 的启动流程必须完整执行包括调用 SystemInit、初始化时钟、拷贝数据段。如果 Bootloader 跳转前没关中断Application 启动时可能被残留的中断打断导致跑飞。还有一个坑是向量表偏移。Application 的向量表不在 Flash 起始地址需要设置 SCB-VTOR 寄存器指向 Application 的向量表。如果忘了这一步中断会跳到 Bootloader 的向量表行为完全错乱。STM32 里可以用NVIC_SetVectorTable或者在启动文件里配置 VECT_TAB_OFFSET。4.3 升级协议的可靠性设计IAP 的升级数据通常通过 UART、CAN、以太网、无线等方式传进来。传输过程必须做可靠性设计否则一个字节出错就可能导致固件损坏、设备变砖。基本做法是分帧传输 校验 重传。每帧数据带序号和 CRC接收方校验通过后回 ACK不通过回 NAK 要求重传。整包固件传完后还要做一次整体校验比如 CRC32 或 SHA256确认无误后才写入 Application 区。更稳妥的做法是双备份 回滚。新固件先写到升级区校验通过后标记为待激活然后 Bootloader 在下次启动时把它搬到 Application 区。如果搬运后启动失败可以用看门狗超时判断就回滚到旧版本。这样即使升级过程中断电设备也不会变砖。注意IAP 升级过程中绝对不能断电尤其是擦写 Flash 的阶段。如果产品使用场景无法保证供电稳定一定要设计掉电保护比如用超级电容撑住擦写完成或者采用双区方案保证任何时刻都有一个可用的固件。5. 三者如何配合一个完整的固件生命周期5.1 研发、量产、维护三阶段的分工把 ISP、ICP、IAP 放到产品生命周期里看分工就很清晰了。研发阶段主要用 ISP/ICP。工程师需要频繁烧录、调试、改代码用调试器连着 SWD 最方便能烧能调能看变量。这个阶段不太在意效率在意的是灵活性和可调试性。量产阶段用 ICP 配合治具。这时候固件已经稳定追求的是烧录速度和一致性。治具 离线烧录器是主流方案每片板子的烧录时间要精确控制烧录日志要留存以便追溯。维护阶段用 IAP。产品已经到用户手里了不可能召回烧录只能通过通信接口远程升级。这时候 Bootloader 的健壮性直接决定升级成功率也是售后成本的关键。5.2 从 ISP 到 IAP 的平滑过渡实际项目中这三个阶段不是割裂的。一个常见的做法是研发阶段用 ISP 烧录一个带 IAP 功能的 Bootloader 和 Application之后所有更新都走 IAP。这样产线只需要烧录一次后续维护全走远程。这里的关键是 Bootloader 要足够稳定因为它一旦损坏就只能回到 ISP 用调试器救砖。所以 Bootloader 代码要尽量简单不要放复杂逻辑不要依赖外部晶振用内部 RC 时钟更稳并且要留一个强制进入升级模式的入口比如某个引脚拉低或者收到特定命令就停在 Bootloader 等待升级。5.3 烧录工具链的选型建议工具链方面研发用厂商官方调试器ST-Link、J-Link、DAPLink配合官方 IDE 就够了。量产建议用专业烧录器比如支持脱机烧录、支持多路并行、支持自动校验的设备。选型时重点看这几点支持的芯片型号是否覆盖你的产品线、烧录速度、是否支持加密烧录、是否有完善的版本管理和日志功能。如果产品有安全需求还要考虑烧录时的固件加密。有些烧录器支持在烧录过程中对固件加密芯片运行时解密执行防止固件被读出。这个功能在量产阶段尤其重要因为治具和烧录文件一旦泄露固件就暴露了。阶段推荐方式工具关注点研发ISPST-Link/J-Link可调试性、灵活性量产ICP治具离线烧录器速度、一致性、日志维护IAP通信接口Bootloader可靠性、回滚能力6. 新手最容易混淆的几个问题6.1 ISP 和 IAP 能同时用吗能而且很常见。芯片里烧一个 BootloaderBootloader 支持通过 UART 接收新固件这是 IAP同时芯片的 SWD 接口保留着研发阶段还能用 ISP 直接烧录。两者互不冲突因为 SWD 是硬件调试接口独立于用户程序。但要注意如果 Application 里把 SWD 引脚复用成了普通 IOISP 就连不上了。所以要么保留 SWD 引脚要么在程序里留一个解锁机制比如上电时检测某个引脚状态决定是否初始化 SWD。6.2 IAP 升级失败变砖了怎么救如果 Bootloader 还在通常不会真变砖。可以强制进入 Bootloader 的升级模式重新传一份固件。如果 Bootloader 也坏了那就只能回到 ISP用调试器重新烧录。所以产品设计时一定要把调试接口引出来哪怕量产时不用留着救砖也是好的。6.3 烧录次数有上限吗Flash 有擦写寿命一般在 1 万到 10 万次之间。研发阶段频繁烧录要注意别在一块板子上反复烧几万次。量产时每片只烧一次完全不用担心。IAP 升级如果太频繁也要考虑寿命不过正常产品的升级频率远低于寿命上限。6.4 为什么我的芯片烧录后不运行这个问题原因很多按概率排一是烧录地址错了比如 bin 文件应该烧到 0x08000000 却烧到了 0x00000000二是复位电路有问题芯片没正常复位三是时钟配置错误程序跑飞四是 BOOT 引脚状态不对芯片从错误的存储区启动。排查时先用调试器连上看 PC 指针停在哪基本就能定位。7. 一些实战中的经验补充7.1 烧录文件的格式选择常见格式有 hex、bin、elf。hex 带地址信息烧录工具能自动识别地址bin 是纯二进制必须手动指定起始地址elf 带调试信息适合调试但不适合量产。量产建议用 hex避免地址搞错。如果只有 bin一定要在作业指导书里写清楚烧录地址并且用工具做二次确认。7.2 批量烧录的序列号管理很多产品需要每台设备有唯一序列号。这个序列号可以在烧录时写入芯片的特定区域比如 Flash 末尾或者 OTP 区。烧录器一般支持从文件或数据库读取序列号烧一片写一个。要注意序列号的分配和记录避免重复或跳号否则售后追溯会乱。7.3 烧录后的功能自检烧录完不能直接打包出货要做功能自检。最简单的做法是让 Application 启动后输出一个特定的心跳信号或者通过通信接口返回版本号产线工装检测到这个信号就判定烧录成功。更严格的做法是跑一遍自检程序检测各个外设是否正常。这一步能拦下不少烧录不良品。7.4 关于加密烧录的实际考量如果产品有固件保护需求量产时开启加密烧录。但要注意加密烧录会增加烧录时间而且一旦密钥丢失后续升级和维护都会受影响。所以密钥管理要有制度不能只存在某个工程师的电脑里。另外加密烧录和 IAP 升级要配合好升级时的固件也要用同样的加密方式否则 Bootloader 解不开。8. 写在最后的一点个人体会ISP、ICP、IAP 这三个概念初看像是三个平行的技术名词实际用起来才发现它们是一条链上的不同环节。研发时用 ISP 图方便量产时用 ICP 图效率维护时用 IAP 图省事。真正把产品做扎实的团队往往在研发阶段就把 IAP 的框架搭好量产时只烧一次后面全靠远程升级既省了产线成本也降低了售后难度。我自己踩过最大的坑是在一个项目里把 Bootloader 写得太复杂结果升级时偶发失败排查了两周才发现是 Bootloader 里用了外部晶振而某些批次的板子晶振起振慢导致 Bootloader 跑飞。后来改成内部 RC 时钟问题立刻消失。这个教训让我明白Bootloader 的代码要笨一点越简单越可靠花哨的功能都放到 Application 里去做。如果你刚开始接触烧录建议先拿一块开发板把 ISP 流程走通再自己写一个最简单的 Bootloader 实现 IAP亲手做一遍比看十篇文章都管用。烧录这件事理论不难难的是各种边界情况和量产细节而这些只有真正上手才会遇到。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进