1. 芯片烧录到底在烧什么先把概念理清楚刚入行那会儿我第一次听到“烧录”这个词脑子里浮现的是拿烙铁往板子上怼的画面。后来才知道这跟焊接半毛钱关系没有烧录指的是把固件代码写进芯片内部存储器的过程。你可以把它理解成给一块空白芯片“装系统”——芯片出厂时里面什么都没有或者只有厂家预置的引导程序必须通过烧录把咱们写的程序灌进去它才能干活。这个动作在量产环节叫“下载”“编程”“烧写”英文里常说的 Program、Flash、Download 都是它。核心逻辑就一句话把编译好的二进制文件通过某种物理接口写进芯片的 Flash 或 ROM 里。那为什么会有 ISP、ICP、IAP 这三个词因为它们回答的是同一个问题的不同侧面——“在什么时间、用什么方式、通过什么通道把代码写进去”。这三个概念经常被混着用甚至有些老工程师也说不清楚区别但你在选型、量产、做OTA升级的时候分不清它们是要吃大亏的。我先把最核心的区分摆出来后面再逐个拆维度ISPICPIAP全称In-System ProgrammingIn-Circuit ProgrammingIn-Application Programming谁在操作芯片出厂自带的BootROM外部烧录器/编程器用户程序自己代码在哪运行芯片内部固化的引导程序烧录器内部已经跑起来的用户固件典型场景产线首次烧录、串口下载产线批量烧录、离线烧录现场OTA升级是否需要拆芯片不需要不需要不需要依赖什么芯片自带Bootloader调试接口SWD/JTAG用户自己实现的升级逻辑这张表你先记住后面每一节我都会展开讲背后的原理和实操细节。2. ISP芯片自带的“急救通道”2.1 ISP 的本质是芯片里的 BootROM 在干活ISP 全称 In-System Programming翻译过来叫“在系统编程”。关键词是“在系统”——意思是芯片已经焊在板子上了你不用把它拆下来直接通过预留的接口就能把程序写进去。它之所以能实现是因为芯片出厂时厂家在硅片里固化了一段BootROM 程序。这段程序你改不了、删不掉上电时芯片会先判断某个引脚的电平或者某个寄存器的状态如果满足进入 ISP 模式的条件就执行 BootROM 里的代码等着你通过串口、USB、CAN 等接口把新固件传进来。拿 STM32 举例BOOT0 拉高、BOOT1 拉低复位后芯片就进入 System Memory 启动模式这时候它跑的就是厂家预置的 Bootloader你可以用串口通过特定的协议把 hex 或 bin 文件发过去。这个过程就是典型的 ISP。注意ISP 用的 Bootloader 是芯片厂家写死的协议也是厂家定的你只能按它的规矩来。不同厂家的 ISP 协议完全不通用STM32 的串口 ISP 协议和 GD32 的就不一样。2.2 ISP 的典型操作流程以最常见的 STM32 串口 ISP 为例完整流程是这样的硬件准备USB 转 TTL 模块一个TX 接芯片的 RXRX 接芯片的 TX共地。BOOT0 接高电平通常接 3.3VBOOT1 接低电平接地。上电复位给板子重新上电芯片进入 BootROM 的 ISP 模式。打开烧录工具用 STM32CubeProgrammer 或者 FlyMcu 这类工具选择串口模式配置波特率常用 115200 或 57600。连接芯片点击“连接”工具会发送同步字节芯片回应后建立通信。选择固件加载编译好的 .hex 或 .bin 文件。执行烧录点击下载工具把数据分包发过去芯片的 BootROM 负责写入 Flash。切换回正常运行烧录完成后把 BOOT0 拉低复位芯片就从用户 Flash 启动跑你刚烧进去的程序。这个流程在研发阶段很常用因为不需要额外的烧录器一根串口线就搞定。但到了量产阶段它的缺点就暴露了速度慢、需要手动切换 BOOT 引脚、每颗芯片都要单独操作效率太低。2.3 ISP 的局限与适用边界ISP 最大的优势是“零成本”——不需要买烧录器芯片自带的功能。但它的局限也很明显速度慢串口 ISP 的波特率通常不超过 115200烧一个 256KB 的固件要几十秒。量产时这个时间成本扛不住。依赖 BootROM如果芯片的 BootROM 有 bug或者厂家没有开放 ISP 功能你就用不了。需要预留接口板子上必须留出串口或者 USB 接口并且要能控制 BOOT 引脚的电平。产品定型后这些接口往往会被砍掉。协议不统一换一个芯片品牌工具和流程全变。所以 ISP 最适合的场景是研发调试、小批量试产、现场应急恢复。量产还是得看 ICP。3. ICP量产线上的主力选手3.1 ICP 和 ISP 到底差在哪ICP 全称 In-Circuit Programming翻译过来是“在电路编程”。很多人第一次听到这个词会懵ISP 也是“在电路”啊不拆芯片这俩有什么区别区别在于谁来执行烧录动作。ISP 是芯片自己跑 BootROM 来接收数据ICP 是外部烧录器主动通过调试接口把数据写进去。换句话说ISP 是芯片“自己吃”ICP 是烧录器“喂着吃”。ICP 走的是芯片的调试接口最常见的是 SWDSerial Wire Debug或者 JTAG。烧录器通过这两个接口直接访问芯片内部的 Flash 控制器不需要芯片跑任何程序。芯片哪怕是一片空白的、从来没烧过任何代码的裸片只要调试接口是通的ICP 就能把程序写进去。这就解释了为什么产线上用的都是 ICP不依赖芯片内部任何软件上电就能烧速度快稳定可靠。3.2 产线 ICP 烧录的完整方案一条典型的产线 ICP 烧录工位包含这些要素烧录器比如 J-Link、ST-Link、CMSIS-DAP 等产线常用的是支持脱机烧录的型号比如 J-Link Pro 或者专门的量产型编程器。烧录座/测试架如果是裸片烧录用烧录座如果是板级烧录用测试架pogo pin 探针顶住板子上的测试点。上位机软件负责加载固件、配置烧录参数、记录烧录结果。MES 系统对接量产时每颗芯片的烧录结果要上传到制造执行系统方便追溯。具体操作流程把固件文件通常是 .hex 或 .bin加载到烧录器或者上位机软件里。配置烧录参数目标芯片型号、接口速度、是否校验、是否写选项字节Option Bytes。把板子放到测试架上探针接触 SWDIO、SWCLK、GND、VCC 这几个关键点。触发烧录按下启动按钮或者由测试架自动触发。烧录器通过 SWD 接口连接芯片擦除、写入、校验。校验通过后烧录器输出成功信号MES 记录该板子的序列号和烧录时间。如果失败工位报警板子被标记为不良品。整个过程通常控制在几秒到十几秒比 ISP 快一个数量级。3.3 ICP 烧录中容易踩的坑第一个坑调试接口被禁用。有些固件在代码里把 SWD 引脚复用成了普通 GPIO或者写了选项字节把调试接口关掉了。这时候 ICP 就连不上芯片只能先用 ISP 或者擦除整片的方式恢复。产线上如果遇到这种情况整批板子都得返工。第二个坑供电不稳。ICP 烧录时烧录器需要给板子供电或者至少要和板子共地。如果板子上有大电容或者功耗波动大烧录器供电能力不够就会出现连接不稳定、烧录中途失败的问题。产线上通常会用外部电源单独给板子供电烧录器只负责信号。第三个坑探针接触不良。测试架的探针用久了会氧化、磨损导致接触电阻变大SWD 通信失败。这个问题的表现是“同一块板子有时候能烧有时候不能烧”排查起来很烦。定期更换探针、保持测试点清洁是必要的维护动作。第四个坑选项字节写错。有些芯片的读保护RDP等级、看门狗配置、复位行为都写在选项字节里。如果烧录时误写了读保护芯片会被锁死只能通过整片擦除来解锁。产线上一定要在烧录流程里明确选项字节的配置并且做好首件确认。4. IAP让产品自己给自己升级4.1 IAP 的核心思想程序自己改自己IAP 全称 In-Application Programming翻译过来是“在应用编程”。前面说的 ISP 和 ICP 都是“外部力量”把代码写进去IAP 不一样——它是芯片里已经跑着的程序自己去修改 Flash 里的内容。这个能力在物联网时代变得极其重要。你想想一个设备装在客户现场可能是墙上的智能电表、工厂里的传感器、或者野外的环境监测站。发现了一个 bug 要修复或者要加一个新功能你不可能派人去现场拆机烧录。这时候就需要设备自己通过网络把新固件下载下来自己完成升级。这就是 IAP。IAP 的实现依赖两个东西一是芯片的 Flash 支持在运行时擦写绝大多数 ARM Cortex-M 芯片都支持二是用户程序里自己实现了升级逻辑。4.2 IAP 的典型分区方案做 IAP 的第一步是把 Flash 分成至少两个区域Bootloader 区存放在 Flash 起始地址负责判断是否需要升级、接收新固件、擦写 APP 区。这段代码通常不参与升级或者升级时格外小心。APP 区存放实际业务逻辑的固件。正常运行时芯片从 APP 区启动。备份区/下载区可选用来暂存下载下来的新固件校验通过后再拷贝到 APP 区。以 STM32F103 为例Flash 总共 256KB常见的分区是这样的区域起始地址大小用途Bootloader0x0800000016KB升级引导程序APP0x08004000200KB业务固件参数区0x080360004KB存储升级标志、版本号备份区0x0803700036KB暂存新固件启动流程是这样的芯片复位后先从 0x08000000 开始执行 BootloaderBootloader 检查参数区里的升级标志。如果标志是“需要升级”就进入升级流程如果标志是“正常运行”就跳转到 APP 区的起始地址把控制权交给业务固件。4.3 跳转代码的关键细节从 Bootloader 跳转到 APP 的代码看起来简单但有几个细节不注意就会翻车// 假设 APP 起始地址是 0x08004000 #define APP_ADDR 0x08004000 typedef void (*pFunction)(void); void jump_to_app(void) { uint32_t app_stack *(volatile uint32_t*)APP_ADDR; pFunction app_entry (pFunction)(*(volatile uint32_t*)(APP_ADDR 4)); // 关闭所有中断 __disable_irq(); // 设置主堆栈指针 __set_MSP(app_stack); // 跳转到 APP 的复位处理函数 app_entry(); }这段代码里最容易出问题的是中断向量表的偏移。APP 程序编译时中断向量表的起始地址默认是 0x08000000但实际它被烧到了 0x08004000。如果不做处理APP 里发生中断时CPU 会去 0x08000000 找中断服务函数结果找到的是 Bootloader 的向量表程序直接跑飞。解决办法是在 APP 的 main 函数开头设置 SCB 的 VTOR 寄存器// APP 的 main 函数开头 SCB-VTOR APP_ADDR;这一句把中断向量表的基地址改到 APP 区中断就能正确响应了。这个坑我踩过不止一次现象是 Bootloader 跳转后 APP 跑几秒就死机或者一进中断就重启排查半天才发现是 VTOR 没设。4.4 IAP 升级流程的完整设计一个可靠的 IAP 升级流程应该包含这些步骤Bootloader 启动检查参数区的升级标志。如果需要升级初始化通信接口串口、CAN、以太网等等待接收新固件。接收固件分包接收每包校验CRC 或校验和写入备份区。整包校验所有数据接收完后对备份区的固件做整体 CRC 校验和上位机发过来的校验值比对。擦除 APP 区校验通过后擦除 APP 区的 Flash。拷贝固件把备份区的数据拷贝到 APP 区。更新标志把升级标志改为“正常运行”记录新版本号。跳转执行跳转到 APP 区运行新固件。如果任何一步失败都要有回滚机制。最简单的回滚是升级标志只有在整包校验通过后才改写如果中途断电或者校验失败下次启动时 Bootloader 发现标志还是“需要升级”就重新走升级流程。APP 区的旧固件虽然被擦了一部分但反正要重新烧不影响。实操心得备份区的存在是为了防止“擦除 APP 区之后、拷贝完成之前”断电导致设备变砖。如果 Flash 空间紧张可以不做备份区直接边接收边写 APP 区但这样一旦断电APP 区就是残缺的必须保证 Bootloader 能重新进入升级模式。两种方案各有取舍看产品对可靠性的要求。5. ISP、ICP、IAP 到底怎么选一张决策表说清楚5.1 按阶段选研发、试产、量产、售后阶段首选方案理由研发调试ISP 或 ICP频繁改代码需要快速烧录ISP 零成本ICP 更稳定小批量试产ICP速度比 ISP 快适合几十到几百片大批量量产ICP 脱机烧录器效率最高可对接 MES适合几千片以上现场升级IAP设备已部署只能远程升级应急恢复ISP设备变砖后用 ISP 强制写入5.2 按芯片型号选不同厂家的支持情况不同芯片对这三种方式的支持程度不一样STM32 系列ISP串口/USB/CAN、ICPSWD/JTAG、IAP 全支持资料最全。GD32 系列兼容 STM32 的生态ISP 和 ICP 基本一致IAP 需要自己实现。HC32 系列华大半导体的芯片ISP 通过串口ICP 用 SWDIAP 支持但文档相对少。FPGAISP 通常指通过 JTAG 配置IAP 的概念和 MCU 不太一样更多是动态重配置。5.3 一个常见的误区ISP 和 ICP 不是互斥的很多人以为选了 ICP 就不能用 ISP其实不是。同一块板子可以同时预留串口 ISP 接口和 SWD 调试接口研发阶段用 ISP 快速验证量产用 ICP 提高效率现场出问题用 ISP 恢复。三者是互补关系不是替代关系。6. 实操中那些文档不会告诉你的坑6.1 关于 ISP 的坑串口 ISP 的波特率不是越高越好。STM32 的 BootROM 对波特率有一定容忍度但如果你用的 USB 转串口模块质量差或者线太长高波特率下误码率会飙升表现为“连接成功但烧录到一半失败”。产线上我一般建议用 115200稳定优先。BOOT 引脚的时序很关键。有些板子 BOOT0 是通过电阻分压设置的上电瞬间的电容充电会导致电平不稳定芯片可能误判启动模式。解决办法是在 BOOT0 引脚上加一个小电容滤波或者用跳线帽手动控制。6.2 关于 ICP 的坑SWD 接口的 SWCLK 和 SWDIO 不要走太长。这两个信号对时序敏感走线超过 10cm 就容易出现连接不稳定。如果板子上芯片和测试点的距离远建议在测试点旁边加缓冲器或者降低 SWD 时钟频率。烧录器的固件版本要和上位机软件匹配。J-Link 的固件和 J-Flash 软件版本不匹配时会出现“识别到烧录器但无法连接目标芯片”的问题。产线换烧录器或者升级软件时一定要做首件验证。6.3 关于 IAP 的坑APP 里的中断向量表偏移一定要设。前面说过了这是最常见的翻车点。IAP 升级时要注意看门狗。如果 Bootloader 里开了看门狗升级过程中擦写 Flash 的时间可能超过看门狗超时时间导致芯片复位。解决办法是在升级流程里定期喂狗或者升级前先关掉看门狗。Flash 擦写寿命要心里有数。STM32 的 Flash 擦写寿命通常是 1 万次左右IAP 升级频繁的产品要算一下寿命。如果每天升级一次一年 365 次十年才 3650 次问题不大。但如果设计成每次上电都检查升级就要避免不必要的擦写。升级固件的传输要加校验。串口、CAN、网络传输都可能出错每包数据加 CRC 校验整包再加一次总校验。校验不通过就重传不要怕麻烦。6.4 常见问题速查表现象可能原因排查方向ISP 连接不上BOOT 引脚电平不对万用表量 BOOT0/BOOT1 电压ISP 烧录中途失败波特率太高或线太长降低波特率缩短连线ICP 识别不到芯片SWD 引脚被复用或禁用检查选项字节用 ISP 恢复ICP 烧录不稳定供电不足或探针接触不良外部供电清洁/更换探针IAP 跳转后死机中断向量表未偏移检查 SCB-VTOR 设置IAP 升级后不运行升级标志未正确改写检查参数区读写逻辑IAP 升级中途断电变砖无备份区且 APP 被擦增加备份区或双 Bank 设计7. 从实际项目出发一个完整的 IAP 升级案例7.1 项目背景与需求我之前做过一个工业数据采集器的项目主控是 STM32F103设备安装在工厂车间里通过 RS485 总线和上位机通信。客户的需求是设备部署后能够通过 RS485 远程升级固件不需要拆机。这个需求用 IAP 来实现。RS485 是半双工总线传输速度不快但胜在稳定而且现场已经有现成的布线不需要额外增加硬件。7.2 Flash 分区设计STM32F103C8T6 的 Flash 是 64KB比较紧张。我的分区方案是区域起始地址大小说明Bootloader0x080000008KB升级引导APP0x0800200040KB业务固件参数区0x0800C0001KB升级标志、版本号、CRC备份区0x0800C40015KB暂存新固件Bootloader 只做三件事检查升级标志、接收新固件、跳转 APP。代码量控制在 8KB 以内用 -Os 优化编译。7.3 升级协议设计RS485 上的升级协议我设计得很简单上位机先发“进入升级模式”命令Bootloader 收到后回复确认。上位机发送固件总长度和总 CRC。上位机分包发送固件数据每包 256 字节包内带序号和 CRC。Bootloader 每收到一包校验 CRC正确则写入备份区并回复 ACK错误则回复 NAK上位机重传。所有包发完后Bootloader 计算备份区固件的总 CRC和上位机发来的比对。校验通过擦除 APP 区拷贝固件改写升级标志回复“升级成功”。上位机收到成功回复后发送“重启”命令Bootloader 跳转 APP。这个协议的好处是简单、可靠每包都有校验出错就重传。缺点是速度慢40KB 的固件在 9600 波特率下要传将近一分钟。但工业现场对升级时间不敏感稳定压倒一切。7.4 关键代码片段Bootloader 里判断升级标志的逻辑#define PARAM_ADDR 0x0800C000 #define UPGRADE_FLAG 0x5A5A5A5A typedef struct { uint32_t upgrade_flag; uint32_t app_version; uint32_t app_crc; } param_t; void bootloader_main(void) { param_t *param (param_t*)PARAM_ADDR; if (param-upgrade_flag UPGRADE_FLAG) { // 进入升级模式 enter_upgrade_mode(); } else { // 跳转 APP jump_to_app(); } }APP 里触发升级的逻辑void request_upgrade(void) { param_t *param (param_t*)PARAM_ADDR; // 解锁 Flash HAL_FLASH_Unlock(); // 擦除参数区 FLASH_EraseInitTypeDef erase; erase.TypeErase FLASH_TYPEERASE_PAGES; erase.PageAddress PARAM_ADDR; erase.NbPages 1; uint32_t page_error; HAL_FLASHEx_Erase(erase, page_error); // 写入升级标志 HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, PARAM_ADDR, UPGRADE_FLAG); // 上锁 HAL_FLASH_Lock(); // 复位让 Bootloader 接管 NVIC_SystemReset(); }7.5 实测结果与优化这套方案在实际项目中跑了两年多升级了十几次固件没有出过问题。有几个优化点值得分享第一升级前先备份当前 APP 的版本号。如果新固件有问题可以回退到旧版本。虽然 Flash 空间紧张但版本号只占几个字节值得留。第二升级过程中禁用看门狗。Bootloader 里在进入升级模式后先关掉 IWDG升级完成后再重新初始化。否则擦写 Flash 的时间可能触发看门狗复位。第三RS485 的方向控制要处理好。发送和接收切换时要有足够的延时否则第一字节可能丢失。我在代码里加了 1ms 的延时实测稳定。第四升级完成后不要立即跳转。先回复上位机“升级成功”等上位机确认收到后再跳转。这样上位机知道升级完成了不会重复发送。8. 新手最容易混淆的几个概念辨析8.1 ISP 和 IAP 到底怎么区分很多人分不清 ISP 和 IAP其实记住一句话就行ISP 是芯片厂家提供的升级方式IAP 是用户自己实现的升级方式。ISP 用的 Bootloader 是芯片出厂自带的你改不了协议也是厂家定的。IAP 用的 Bootloader 是你自己写的你想怎么升级就怎么升级协议也是你自己定的。从使用场景看ISP 通常用于研发和应急恢复IAP 用于现场远程升级。ISP 需要人工干预切换 BOOT 引脚、打开工具IAP 可以全自动完成。8.2 ICP 和 JTAG/SWD 的关系ICP 是一种编程方式JTAG 和 SWD 是具体的物理接口。ICP 可以通过 JTAG 实现也可以通过 SWD 实现。现在 ARM Cortex-M 芯片主流用 SWD因为引脚少两根线、速度快、占用资源少。JTAG 需要五根线一般只在复杂的多核调试场景下用。8.3 烧录和调试是一回事吗不是。烧录是把固件写进 Flash调试是让芯片运行到断点、查看变量、单步执行。但两者用的物理接口往往是同一个SWD所以烧录器通常也支持调试功能。J-Link、ST-Link 都是既能烧录又能调试的。8.4 关于“ISP Pipeline”和“ISP 图像处理”搜索热词里出现了“isp pipeline”和“isp 图像处理”这里的 ISP 是 Image Signal Processor图像信号处理器的缩写和 In-System Programming 完全是两码事。图像 ISP 是处理摄像头原始数据的专用硬件负责去马赛克、白平衡、降噪、锐化等。如果你是在摄像头、手机、安防监控领域看到 ISP那说的就是图像处理不是芯片烧录。这两个概念同名不同义搜索资料时要注意区分。9. 工具选型与资源推荐9.1 烧录器怎么选烧录器适用场景优点缺点ST-LinkSTM32 研发调试便宜、官方支持只支持 ST 芯片J-Link多品牌研发量产速度快、支持芯片多价格较高CMSIS-DAP开源方案免费、可自制速度一般脱机烧录器产线量产不依赖电脑、效率高配置复杂9.2 常用软件工具STM32CubeProgrammerST 官方工具支持 ISP、ICP、IAP 多种模式。J-FlashJ-Link 配套软件支持批量烧录和脚本自动化。FlyMcu国产串口 ISP 工具简单易用。OpenOCD开源调试烧录工具支持多种烧录器。9.3 学习路径建议如果你是新手建议按这个顺序学先用 ISP 把一颗 STM32 点亮 LED理解烧录的基本流程。再用 ST-Link 通过 SWD 烧录对比 ISP 和 ICP 的区别。然后写一个最简单的 Bootloader实现串口 IAP 升级。最后研究双 Bank 升级、差分升级、加密升级等高级话题。每一步都要动手做光看文档是学不会的。尤其是 IAP不自己写一遍跳转代码永远不知道中断向量表偏移有多坑。10. 写在最后一些个人体会做了这么多年嵌入式烧录这件事看起来简单但真正做好并不容易。研发阶段随便怎么烧都行但到了量产和售后烧录方案的可靠性直接决定了产品的口碑。我的经验是研发阶段怎么方便怎么来量产阶段怎么稳定怎么来售后阶段怎么远程怎么来。ISP、ICP、IAP 不是三选一而是要根据产品所处的阶段灵活组合。还有一点IAP 的升级协议不要设计得太复杂。我见过有人用 TCP 加 TLS 加自定义加密协议做 IAP结果现场网络环境一差就升级失败设备变砖。工业现场、户外设备通信环境往往很恶劣协议越简单越可靠。每包加 CRC、出错重传、整包校验这三板斧足够应对绝大多数场景。最后分享一个小技巧做 IAP 的时候在 Bootloader 里留一个“强制升级”的入口比如检测某个 GPIO 电平或者接收特定命令。这样即使 APP 跑飞了也能通过这个入口重新升级不至于只能拆机用 ISP 恢复。这个入口可能一辈子用不上但用上的那一次能救你一命。