芯片烧录这个词很多刚入行的朋友第一次听到会觉得挺神秘其实说白了就是给芯片装系统。你拿到一颗全新的MCU或者FPGA里面是空的什么程序都没有烧录就是把编译好的固件写进去让它能跑起来。但问题来了——ISP、ICP、IAP这三个词经常混着出现很多人干了半年也没完全搞明白它们的区别面试被问到就卡壳。这篇内容我打算把这三个概念彻底拆开讲清楚从硬件接口到软件流程从产线量产到现场升级每个环节都配上实际场景和踩坑经验。不管你是刚接触嵌入式的新手还是做了几年但一直没系统梳理过的老手看完都能有个清晰的认知框架。1. 先把烧录这件事的本质说透1.1 芯片为什么需要烧才能用芯片出厂的时候内部的Flash或者ROM是空的或者只有厂家预置的BootROM。你写的C代码经过编译、链接之后变成二进制文件这个文件必须被写进芯片的存储介质里CPU才能取指执行。这个过程就是烧录。打个比方芯片就像一台刚出厂的电脑硬盘是格式化过的但没有任何操作系统。烧录就相当于你用U盘给它装系统。装完之后电脑才能开机进桌面芯片才能跑你的业务逻辑。烧录的本质是对非易失性存储器的编程操作。不同芯片的存储介质不一样STM32用的是内部Flash有些FPGA用的是外部SPI Flash配置芯片还有一些OTP芯片只能烧一次。介质不同烧录方式就不同但核心逻辑是一样的把数据写到指定地址然后让芯片从那个地址启动。1.2 烧录方式的三层分类逻辑很多人搞不清ISP、ICP、IAP是因为没有建立一个分类框架。我习惯按**谁在操作和什么时候操作**这两个维度来分ICP产线上烧录器直接操作芯片的调试接口芯片还没焊到板子上或者刚焊好但没有任何程序ISP板子已经焊好了通过芯片内置的BootROM程序用串口/CAN/USB等通信接口把固件传进去IAP产品已经出货到客户手里了运行中的程序自己把自己更新掉这三个词覆盖了芯片从裸片到量产到现场维护的完整生命周期。你只要记住这个时间线就不会混淆。1.3 三个概念的核心差异对比维度ICPISPIAP操作阶段产线量产开发调试/产线现场升级是否需要BootROM不需要需要需要已有程序通信接口SWD/JTAGUART/CAN/USB任意通常UART/CAN/无线烧录器专用编程器不需要不需要固件来源PC端直接写入PC端通过BootROM传输设备自身获取新固件典型工具J-Link、ST-LinkFlash Loader、STM32CubeProgrammer自定义Bootloader速度最快中等取决于通信方式灵活性低需物理接触中高可远程这张表建议收藏面试前看一眼就能把思路理清。2. ICP产线上最直接的烧录方式2.1 ICP到底在做什么ICP全称In-Circuit Programming中文叫在线编程。注意这里的在线不是指互联网而是指芯片已经在电路板上了。产线上工人把板子放到夹具上夹具的探针顶住芯片的SWD或者JTAG引脚编程器通过调试接口直接把固件写进Flash。这个过程不依赖芯片里任何已有程序。哪怕是一颗全新的、Flash全空的芯片只要调试接口能连上就能烧。因为调试接口是硬件级别的由芯片内部的Debug模块直接控制不需要CPU参与执行任何代码。我见过很多新手问为什么我的板子第一次烧录必须用ST-Link原因就在这里——空芯片没有BootROM之外的任何程序ISP方式虽然也能用但ICP更直接、更可靠。2.2 ICP的硬件连接与信号要求以STM32为例ICP最少需要这几根线SWDIO数据线SWCLK时钟线GND地VCC参考电压有些编程器需要检测目标电压NRST复位线可选但强烈建议接注意NRST这根线很多人不接觉得能省一个引脚。但在产线上如果芯片里已经有一个跑飞的程序不接复位线编程器可能连不上。我踩过这个坑后来所有产线夹具都强制要求接NRST。信号质量方面SWD的时钟频率在产线上一般降到1MHz以下因为夹具探针的接触电阻和寄生电容会影响信号完整性。实验室里跑4MHz没问题产线上老老实实降速稳定性优先。2.3 产线ICP的实操流程与效率优化一条典型的产线烧录工位是这样的工人把PCBA放入夹具气缸压下探针接触测试点编程器检测目标电压确认板子已上电编程器读取芯片ID确认型号匹配擦除Flash写入固件校验写入数据写入选项字节如读保护、看门狗配置编程器给出OK/NG信号夹具松开整个流程如果优化得好一颗STM32G0的256KB固件从接触到完成大概在8-12秒。其中擦除占2-3秒写入占4-6秒校验占2-3秒。效率优化的几个关键点擦除策略如果固件不大用扇区擦除比全片擦除快很多。全片擦除STM32F1要等好几秒按扇区擦就快得多校验方式CRC校验比逐字节比对快但需要芯片端支持并行烧录一拖四、一拖八的编程器很常见一次夹四块板子同时烧固件预加载编程器先把固件缓存在内部RAM里减少PC端通信延迟2.4 ICP的局限性与适用边界ICP最大的问题是必须物理接触。产品封壳之后调试接口就摸不到了没法再用ICP。另外如果板子上没有预留调试接口的测试点产线也没法用ICP。还有一个容易被忽略的点ICP会破坏读保护。如果你在产线上先烧了一个带读保护的固件后面想通过ICP重新烧录编程器需要先执行全片擦除才能解锁。这意味着读保护一旦开启ICP更新固件就必须全擦没法做增量更新。所以ICP最适合的场景就是产线首次烧录以及开发阶段的反复调试。产品出货之后就别指望ICP了。3. ISP不拆壳也能烧的秘诀3.1 ISP依赖的BootROM机制ISP全称In-System Programming中文叫在系统编程。它和ICP最大的区别是ISP不需要调试接口而是利用芯片出厂时固化在BootROM里的一段程序来接收新固件。芯片上电后BootROM先运行。它会检测某个引脚的电平或者某个寄存器的状态判断是否进入ISP模式。如果进入BootROM就通过预设的通信接口通常是UART等待PC端发送固件数据接收完写入Flash然后跳转到用户程序。以STM32为例BOOT0引脚拉高、BOOT1拉低上电后就进入系统存储器启动模式也就是ISP模式。这时候你用串口连上通过STM32CubeProgrammer或者Flash Loader Demonstrator就能烧录。3.2 ISP的触发条件与硬件设计要点ISP能不能用取决于硬件设计有没有预留触发条件。常见的触发方式BOOT引脚组合STM32的BOOT0/BOOT1上电时采样特定引脚电平有些芯片检测某个GPIO在复位时的状态通信接口自动检测部分芯片的BootROM会自动扫描UART/CAN/USB收到特定握手信号就进入ISP硬件设计上如果你希望产品支持ISP升级必须把BOOT引脚引出来或者至少留一个测试点。很多产品为了省成本把BOOT0直接接地那就永远进不了ISP模式只能靠IAP。提示BOOT0引脚建议加一个下拉电阻10K再通过跳线或者测试点控制。这样正常运行时是低电平从Flash启动需要ISP时拉高即可。3.3 用ISP方式烧录的完整操作链路以STM32的UART ISP为例完整流程如下硬件连接USB转TTL模块的TX接芯片RXRX接芯片TXGND共地BOOT0拉高BOOT1拉低如果有的话给板子重新上电注意必须是上电复位不是按复位键打开STM32CubeProgrammer选择UART模式配置波特率通常115200点击Connect软件发送0x7F同步字节芯片BootROM回应ACK0x79连接建立选择固件文件点击Download等待写入完成软件显示进度和校验结果BOOT0拉低重新上电芯片从Flash启动运行新固件整个过程不需要ST-Link只需要一个几块钱的USB转串口模块。这也是为什么很多低成本产品选择ISP作为产线烧录方式。3.4 ISP在产线量产中的实际表现ISP在产线上的效率比ICP低因为UART的波特率有限而且每次都要手动切换BOOT引脚。但它的优势是硬件成本低——不需要昂贵的编程器一个工控机带多个串口就能同时烧多块板子。我见过一个做智能电表的朋友产线用ISP方式一台工控机带16路串口同时烧16块板子每块板子固件128KB波特率921600大概15秒完成。虽然比ICP慢但硬件成本只有ICP方案的十分之一。ISP的另一个好处是可以远程触发。如果你的设备有无线模块理论上可以通过无线模块接收固件然后控制BOOT引脚进入ISP模式。但这种方式比较绕实际项目中更多人直接用IAP。4. IAP产品出货后的自我更新能力4.1 IAP的本质程序自己改自己IAP全称In-Application Programming中文叫在应用编程。它的核心思想是芯片里已经有一个正在运行的程序通常叫Bootloader这个程序负责接收新固件、擦除旧固件、写入新固件然后跳转到新固件执行。关键点在于IAP不需要任何外部编程器也不需要BootROM的ISP模式。整个升级过程由芯片自己完成外部只需要提供新固件的二进制数据。这就好比你的手机系统更新——手机里已经有一个更新程序它从服务器下载新系统包验证之后写入存储然后重启切换到新系统。芯片的IAP是一模一样的逻辑。4.2 Bootloader与App的分区设计做IAP的第一步是规划Flash分区。以STM32F103C8T664KB Flash为例典型分区区域起始地址大小用途Bootloader0x0800000012KB负责升级逻辑App0x0800300048KB用户业务程序参数区0x0800F0004KB存储升级标志、版本号Bootloader永远不升级或者极少升级它负责上电后检查参数区是否有升级请求标志如果有进入升级模式通过UART/CAN/无线接收新固件接收完成后校验固件完整性CRC32擦除App区写入新固件清除升级标志跳转到AppApp区就是你的业务代码它需要在需要升级时向参数区写入升级标志然后触发软复位复位后Bootloader检测到标志进入升级流程4.3 中断向量表重映射的坑这是IAP最容易出问题的地方。STM32的中断向量表默认在0x08000000但App程序是从0x08003000开始的。如果不做重映射App里的中断会跳到Bootloader的向量表直接跑飞。解决方法是在App的main函数开头尽早执行// 设置向量表偏移为App起始地址 SCB-VTOR 0x08003000;或者在Keil的Target设置里把IROM1的起始地址改成0x08003000同时在代码里调用NVIC_SetVectorTable()。注意这个操作必须在任何中断使能之前完成。我见过有人在main函数最后才设置VTOR结果串口中断先触发了直接跳到Bootloader的向量表程序卡死。4.4 升级标志的存储与掉电保护升级标志不能随便存在RAM里因为复位就丢了。必须存在Flash或者备份寄存器BKP里。存在Flash里要注意写Flash之前必须先擦除整个扇区擦除和写入过程中如果掉电标志可能处于不确定状态建议用双备份CRC校验的方式存储标志一个可靠的方案是在参数区存两个结构体每个都包含升级标志、固件长度、固件CRC、结构体自身的CRC。读取时两个都读取CRC正确的那个。写入时先写备份区再写主区。4.5 IAP升级流程的完整时序以UART IAP为例完整时序如下App运行中收到升级命令比如上位机通过串口发送特定帧App向参数区写入升级标志和固件信息App调用NVIC_SystemReset()触发软复位芯片复位Bootloader先运行Bootloader读取参数区发现升级标志有效Bootloader通过UART发送准备接收信号上位机开始发送固件数据包Bootloader逐包接收、写入App区全部接收完成后Bootloader计算CRC并与参数区存储的CRC比对校验通过清除升级标志跳转到App校验失败保留升级标志等待重新传输整个过程如果掉电Bootloader下次上电会重新检测标志继续升级流程。这就是为什么Bootloader必须足够健壮——它是整个升级机制的最后一道防线。5. 三个概念在实际项目中的选择逻辑5.1 什么阶段用哪种方式我总结了一个简单的决策树芯片还没焊到板子上只能用ICP因为没有任何接口可以通信板子焊好了产线首次烧录ICP或ISP都行看成本和效率要求开发阶段反复调试ICP最方便ST-Link一插就能烧产品出货后需要升级只能用IAP因为调试接口和BOOT引脚都摸不到产品出货后需要救砖如果IAP的Bootloader也挂了只能拆壳用ICP5.2 成本与效率的权衡方案硬件成本单板烧录时间适用产量ICP一拖一编程器300-800元8-15秒小批量ICP一拖四编程器2000-5000元3-5秒/板中大批量ISP单路USB转串口10元15-30秒小批量ISP多路工控机多串口卡10-20秒/板中批量IAP无额外硬件取决于通信方式现场升级产线量产首选ICP一拖多效率最高。如果预算有限且产量不大ISP也能凑合。IAP不是产线方案是售后方案。5.3 常见误区与纠正误区一ISP和IAP是一回事不对。ISP用的是芯片出厂自带的BootROMIAP用的是你自己写的Bootloader。ISP的协议是芯片厂家定的IAP的协议是你自己定的。误区二有了IAP就不需要ICP了不对。IAP的Bootloader本身也需要通过ICP或者ISP烧进去。而且如果Bootloader被破坏只能通过ICP救砖。误区三IAP升级一定要用UART不对。IAP的通信接口可以是UART、CAN、SPI、I2C、USB甚至是无线模块蓝牙、WiFi、LoRa。只要Bootloader能驱动那个接口就能用来传输固件。误区四ICP只能烧录不能调试不对。ICP用的SWD/JTAG接口本身就是调试接口既能烧录也能单步调试、查看变量、设置断点。ISP和IAP只能烧录不能调试。6. 新手最容易踩的五个坑6.1 BOOT引脚状态不对导致ISP连不上这是最最常见的问题。STM32进ISP需要BOOT01、BOOT10而且必须是上电复位时采样。很多人按了复位键但复位键只复位系统不复位BOOT引脚的采样电路所以进不了ISP。正确做法先设置好BOOT引脚电平然后断电再上电。或者用串口工具的DTR/RTS引脚自动控制BOOT0和NRST实现一键进入ISP。6.2 IAP跳转后中断不响应前面提过向量表偏移没设置。但还有一种情况Bootloader里开启了某个外设比如串口跳转到App之前没有关闭。App重新初始化这个外设时因为外设已经在运行状态初始化可能失败。解决方法Bootloader在跳转前调用DeInit()关闭所有使用的外设关闭全局中断然后跳转。6.3 Flash擦除时间不够导致写入失败STM32的Flash擦除是按扇区进行的一个扇区擦除可能需要几十毫秒。如果你在擦除后立即写入而没有等待BSY位清零写入会失败。正确做法每次擦除后轮询FLASH_SR寄存器的BSY位直到清零再继续。或者使用HAL库的HAL_FLASHEx_Erase()它内部已经处理了等待。6.4 固件校验不严导致变砖IAP升级时如果固件传输过程中出现误码而Bootloader没有做CRC校验直接把错误数据写进FlashApp就跑不起来。更糟糕的是如果Bootloader把升级标志清了下次上电直接跳转到错误的App设备就变砖了。正确做法Bootloader必须对接收到的固件做CRC32校验校验通过才清除升级标志。校验失败则保留标志等待重新传输。6.5 读保护开启后无法通过ICP重新烧录有些产品为了安全在产线烧录后开启了读保护。但读保护开启后ICP无法读取Flash内容也无法直接重新烧录。必须先执行全片擦除解锁才能重新烧录。如果产品已经封壳读保护又开着那就只能拆壳用ICP全擦。所以开启读保护之前一定要确认IAP升级通道是可靠的。7. 从热词看行业关注点最近网上关于芯片烧录的热搜词挺有意思我挑几个说说。isp pipeline和isp图像处理这里的ISP指的是Image Signal Processor图像信号处理器和芯片烧录的ISP完全是两码事。图像ISP是处理摄像头原始数据的做去马赛克、白平衡、降噪这些。搜索的时候要注意区分别搞混了。stc isp去弹窗STC单片机用STC-ISP工具烧录时软件会弹窗提示一些信息。很多用户觉得烦想找去弹窗的方法。这其实是个软件使用技巧和烧录原理无关。hc32l136 iap和stm32h750vbt6 iap这两个是具体型号的IAP实现。HC32L136是华大的低功耗MCUSTM32H750是ST的高性能MCU。不同芯片的IAP实现细节不同主要是Flash控制器和中断向量表地址不一样。iap boot里面定义的变量复位后会怎样这个问题问得好。Bootloader里定义的全局变量如果放在RAM里复位后值是不确定的除非有备份寄存器或者特意初始化。如果放在Flash里作为常量复位后值不变。所以升级标志不能存在普通RAM变量里必须存在Flash或者BKP寄存器里。fpga ispFPGA的ISP通常指通过JTAG或者SPI接口对配置Flash进行编程。FPGA本身是SRAM工艺掉电就丢配置所以需要外挂一个SPI Flash存储配置数据。上电时FPGA从Flash读取配置。更新时通过JTAG烧录Flash或者通过FPGA内部的硬核处理器做IAP。8. 一套可复用的IAP框架设计思路8.1 分区表的灵活定义不要把分区地址写死在代码里用宏定义或者配置文件管理#define BOOTLOADER_START 0x08000000 #define BOOTLOADER_SIZE (12 * 1024) #define APP_START (BOOTLOADER_START BOOTLOADER_SIZE) #define APP_SIZE (48 * 1024) #define PARAM_START (APP_START APP_SIZE) #define PARAM_SIZE (4 * 1024)这样换芯片或者调整分区时只改这几个宏就行。8.2 升级协议的帧格式设计一个简单的升级协议帧格式字段长度说明帧头2字节0xAA55命令1字节0x01开始升级0x02数据包0x03结束长度2字节数据域长度数据N字节固件数据或参数CRC162字节从帧头到数据的CRCBootloader收到帧后先校验CRC16通过后再处理。这样能过滤掉大部分传输错误。8.3 双Bank升级的进阶方案如果芯片Flash足够大可以做双Bank升级Bank A运行当前固件Bank B接收新固件。升级完成后切换启动地址。这样即使升级过程中掉电原来的固件还在不会变砖。STM32F4、F7、H7系列都支持双Bank Flash硬件层面就能做地址交换。低端芯片没有双Bank就只能靠Bootloader的健壮性来保证。8.4 版本回滚机制升级后如果新固件有问题需要能回滚到旧版本。实现方式参数区保留旧固件的备份需要额外Flash空间或者参数区记录旧固件的版本号和CRC但旧固件本身不保留回滚时重新传输旧固件第一种方式更可靠但占空间第二种方式省空间但回滚需要重新传输。9. 调试IAP时我常用的几个手段9.1 用LED和串口打印做状态指示Bootloader里没有复杂的调试手段最简单的就是在关键步骤翻转LED或者打印串口信息。比如进入BootloaderLED快闪3次收到升级命令LED常亮写入FlashLED慢闪校验通过LED快闪5次后熄灭校验失败LED常亮不灭这样产线工人不用看串口看LED就知道升级成功还是失败。9.2 用J-Link直接读取Flash内容验证IAP升级完成后用J-Link连上芯片直接读取App区的Flash内容和原始固件二进制文件比对。如果一致说明写入正确。如果不一致检查写入地址和长度。9.3 模拟掉电测试在IAP升级过程中随机断电然后重新上电看Bootloader能不能正确处理。这个测试非常关键能暴露很多边界问题。我一般会做至少20次随机掉电测试确保没有一次变砖。9.4 用看门狗防止Bootloader卡死Bootloader里也要开看门狗。如果升级过程中通信中断Bootloader不能一直死等应该超时后复位重新检测升级标志。看门狗超时时间设置成比正常升级时间长一些比如30秒。10. 关于烧录这件事的一些个人体会干了这么多年嵌入式烧录这件事看起来简单但真正做好不容易。ICP、ISP、IAP这三个概念本质上对应的是芯片生命周期的三个阶段生产、部署、维护。理解了这个时间线很多问题就迎刃而解了。我见过太多项目在IAP上翻车原因往往不是技术难度大而是细节没考虑到——向量表忘了重映射、升级标志掉电丢了、CRC校验没做、看门狗没开。这些问题在实验室里可能跑一百次都没事一到现场就出问题。如果你正在做IAP相关的开发我的建议是先把Bootloader写扎实把各种异常情况都考虑进去然后再做App。Bootloader是最后一道防线它挂了设备就真成砖了。另外产线烧录方案要尽早确定不要等到产品快量产了才发现ICP夹具没做、ISP引脚没留、IAP分区没规划。这些硬件层面的东西后期改起来成本很高。最后说一个实际经验不管用哪种烧录方式永远保留一个ICP救砖通道。哪怕产品封壳了也在板子上留几个测试点关键时刻能救命。我见过一个项目产品装在现场机柜里IAP升级失败变砖最后派人爬上去拆壳用ST-Link救回来的来回折腾了两天。如果当初留了测试点十分钟就能解决。
阅读完成 · 觉得有帮助?