资讯动态

芯片烧录三种方式:ICP、ISP、IAP区别与IAP Bootloader实操

发布时间:2026/9/29 21:05:40 来源:尧图企业网站定制
做嵌入式开发这些年我几乎每周都会碰到有人问“芯片烧录到底是什么”。很多新手把烧录理解成“把电脑里的代码传到板子上”这个说法不算错但太粗糙了。准确地说烧录是把编译好的固件——也就是我们常说的hex文件、bin文件——写进芯片内部的非易失性存储区典型的就是Flash。断电不丢一上电芯片就从Flash里把指令一条条取出来执行你的程序就跑起来了。为什么这件事值得掰开揉碎讲清楚因为“写进Flash”这个动作在实际工程里有好几种完全不同的实现路径而你做的每一个选择都直接影响开发效率、量产成本和现场维护的难度。ISP、ICP、IAP这三个缩写就是三种完全不同的“把程序写进芯片”的方式。很多新人在三个词面前一脸懵网上资料又多又碎所以我干脆把概念、原理、适用场景、实操坑串起来写一篇争取让你一次看明白。这篇文章适合谁刚接触单片机的学生、正在做第一版产品的硬件工程师以及想搞懂“产品到底怎么通过串口或网络升级固件”的爱好者都能从里面找到自己需要的坐标系。基础概念我会讲透实操部分以STM32为例展开其他Cortex-M系列的单片机逻辑也是相通的。1. 芯片烧录是什么先在脑子里建立一个完整画面1.1 烧录的本质不是一个“复制粘贴”动作先纠正一个直觉误区。很多人以为烧录就是把文件复制到芯片里像U盘拷文件一样。不完全对。Flash的写入需要按照严格的时序由芯片内部控制器或者外部烧录器按协议把数据一页一页地擦除、再写入。而且写之前通常要先擦除因为Flash物理特性决定了它的存储单元只能从1变成0想把它从0变回1只能整片或整页擦除。所以一个完整的烧录流程是“擦除写入校验”三步缺一不可。打个生活比方。Flash就像一块写满字的黑板你想改一个字没办法只擦那一个字得把整行甚至整块擦掉重写。这就决定了烧录过程没法像普通文件复制那么简单你需要一个“能写得进去的通道”。ICP、ISP、IAP三种方式本质上是三种不同的“写入通道”通道的开在哪、谁在控制、需要什么前提条件都不一样。1.2 芯片里到底烧了什么东西烧进去的内容分两种常见格式hex和bin。hex是带地址信息的文本格式每一行都包含数据对应放的地址烧录器根据这些地址把数据挨个放到位。bin是纯二进制数据没有地址信息烧录的时候必须由你告诉烧录器“从哪个地址开始放”。开发调试阶段一般拿hex说事量产时的批量烧录文件经常是bin因为产线只关心裸数据。还有一个容易被忽略的点一个完整的固件里不只是你的代码还包括中断向量表、栈初始值、启动代码。芯片上电会先取栈指针再跳转到复位向量最后才进入main函数。这部分你平时看不见但它真实存在而且正因为它的存在后面讲IAP跳转时才不能简单地把跳转理解成“一个函数调用”。2. 三种烧录方式逐个拆解ICP、ISP、IAP到底是什么为什么会有三种方式答案很现实因为不同场景的需求差异太大了。开发阶段你想边改代码边调试需要一个高速稳定的通道产线阶段你希望操作简单、成本低、速度快产品卖出去之后你还想远程更新固件。没有任何一种方案能同时完美满足全部场景于是三种方式并存。它们之间的关系不是互相替代而是互相配合。2.1 ICP最“硬核”的烧录方式ICP的全称是In-Circuit Programming在电路编程。理解它有个关键词调试器。这种方式通过JTAG或者SWD接口用ST-Link、J-Link、DAP-Link这类调试器直接和芯片内部的调试总线通信控制内核把程序写进Flash。因为调试器直接操作芯片内核所以它不光能烧录还能在线调试、下断点、看变量、单步执行。ICP这个名字最早强调的语境是“芯片已经焊在电路板上了我还要给它烧程序”。相比早期先烧录再把芯片贴到板子上的做法ICP的好处显而易见板子焊完统一烧产线流程好安排得多。后来SWD接口普及只需要两根数据线加电源地就能完成烧录加调试所以现在几乎所有Cortex-M芯片的开发板默认都用SWD烧录。ICP的优缺点也一并说清楚。优点是快、稳定、支持在线调试缺点是硬件上必须预留调试接口调试器本身要花钱而且量产阶段如果一台一台接调试器下载效率需要认真评估。我自己开发时天天用但产线方案上不会让工人拿J-Link一个个点。2.2 ISP不需要调试器的烧录方式ISP全称In-System Programming在系统编程。这里的“系统”指的就是你的整块电路板。它主要利用芯片出厂前固化在系统存储区里的一段引导程序。芯片厂商在生产芯片时会在内部专门放一段Bootloader这段程序认识串口UART、USB等通信协议。你只需要把对应引脚接出来通过USB转TTL或直接USB线连电脑再用厂商提供的下载工具把固件发给这段引导程序由它替你写进Flash。这里要说一个常见误区很多人把STM32串口下载叫UART下载把51单片机下载叫ISP其实原理大同小异都是靠出厂Bootloader。STC的51单片机出厂固化ISP引导程序所以下载软件直接叫stc-ispSTM32的串口下载靠的是System Memory里的出厂Bootloader通过BOOT0/BOOT1引脚选择进入。核心思想一模一样。ISP最大的好处是省掉调试器一条几块钱的USB转TTL串口线就能烧录特别适合业余玩家、低成本开发和部分小批量产线。缺点也明显速度通常不如ICP不能在线调试而且出厂Bootloader支持的通信协议是厂家定死的灵活性有限。如果你只是想把程序下进去跑不打算调试ISP完全够用。2.3 IAP程序自己烧自己IAP全称In-Application Programming在应用编程。这是三种方式里最灵活、也最需要自己动手的一种。思路是这样芯片出厂后你自己在Flash里写一个简单的引导程序Bootloader芯片上电先执行它。Bootloader判断自己需不需要升级如果需要就通过串口、USB、SPI、网络等任意通道把新固件收过来写到Flash里另一块区域然后跳过去运行新程序。这就是“在应用编程”——程序在运行过程中自己完成了对自己所在芯片Flash的更新。IAP最典型的落地场景是OTA升级。产品已经到用户手里了不可能派人拆机接调试器。只要设备联网服务器下发新固件Bootloader收下来、校验通过、跳转运行一个远程升级就完成了。stm32h750vbt6这类芯片经常被用在IAP方案里因为它的片上Flash不大但可以通过QSPI外挂大容量FlashApp放在外部Flash升级逻辑更灵活。类似地gd32f103、hc32l136这些国产芯片做IAP升级现在已经很常见工控设备、物联网终端里到处都是。IAP的难点在于Bootloader和App都运行在同一颗芯片上你得自己规划内存布局、写通信协议、处理固件校验和跳转细节这也是本文第4部分要重点展开的原因。说白了前两种烧录方式是厂家把路铺好了你走就行IAP需要你自己铺路。2.4 一张表看清三者区别对比项ICPISPIAP全称In-Circuit ProgrammingIn-System ProgrammingIn-Application Programming编程触发方外部调试器芯片出厂自带的Bootloader用户自己写的Bootloader主要接口JTAG / SWDUART / USB / SPI等UART / USB / SPI / 网络等是否需要调试器需要不需要不需要是否需要用户写Bootloader不需要不需要需要能否在线调试能不能一般不能典型场景开发调试、产线烧录低成本开发、小批量产线现场升级、远程OTA速度快中等取决于通道通常中等这张表记住一句话就够了ICP靠外部调试器ISP靠出厂BootloaderIAP靠你自己的Bootloader。三个词的核心区别不在接口在“谁在帮你写Flash”。2.5 一个容易闹笑话的坑ISP还有别的意思这里必须插一段自嘲式的提醒。我入行不久时上网查ISP资料一搜出来一堆图像处理工程师在聊“ISP pipeline”当时非常困惑。后来才搞清楚芯片烧录里的ISP是In-System Programming而图像处理里的ISP是Image Signal Processor图像信号处理器。还有做三维视觉的同学一听到ICP第一反应是Iterative Closest Point迭代最近点配准算法跟烧录完全不沾边。FPGA的“ISP”则是另一种在系统配置方式层级又不一样。所以我现在的习惯是跟人沟通涉及这些缩写一定带上场景比如说“串口下载”“SWD烧录”“远程OTA升级”或者直接讲全称。否则大家很可能在鸡同鸭讲搞半天发现讨论的根本不是同一个东西。3. 开发、量产、现场升级三种方式如何配合使用理解了概念接下来就是实际工程里到底怎么选。这些年我经手的项目几乎没有只靠一种烧录方式的都是组合使用。从开发到量产再到售后维护每个阶段的最优解不同下面分开讲。3.1 开发调试阶段ICP几乎是默认答案如果项目处于软件调试阶段每天要改代码、烧录、看现象SWD调试器加ICP这种方式最顺手。原因有两个。第一速度快代码稍微改动点一下下载几秒钟烧完。第二也是更重要的它支持在线调试。你可以在代码里打断点、看变量、单步执行出问题能很快定位。ISP和IAP都不具备这个能力因为它们的烧录过程不经过调试总线自然也没法把调试器挂上去。有人问预算紧张用串口ISP行不行。当然可以我早期没有调试器时也这么干但你需要忍受两件事一是每改一次代码要手动切换BOOT引脚进入下载模式二是一旦程序跑飞只能靠串口打印慢慢排查。等复杂度上来效率非常吃亏。省了一百块调试器耽误的时间远超这个数。3.2 量产烧录效率和成本之间的平衡量产阶段产线工人不关心你代码怎么写只关心“烧得准、烧得快、操作傻瓜化”。这时ICP和ISP各有一席之地。产量不大几百片级别用一台脱机烧录器加烧录夹具按一下按钮烧一片完全够用。产量上万一般考虑两条路找烧录厂在贴片前用烧录座集中烧录或者在产线上用多路烧录器一次同时烧好几片。这里有一个特别想提醒的点量产烧录一定要重视校验环节。我见过不少电路板到用户手里才出问题查到最后是烧录数据有个别字节错了产线签收时根本看不出来。所以不管用哪种方式烧录都要确保烧录工具开启了CRC校验或者回读校验宁可烧录时间多几秒也不能让坏数据出厂。这个习惯要刻在骨子里。3.3 现场升级IAP是绕不开的方案产品到了现场不管是工业设备还是消费电子都不可能让用户拆开外壳去接调试器。哪怕硬件预留了烧录接口普通用户也不会操作。所以只能走IAP设备通过网络、串口、USB甚至蓝牙把固件接收进来由Bootloader完成自我更新。这几年国产MCU的IAP应用明显增加gd32f103的IAP升级在工控和物联网设备里大量出现hc32l136这类低功耗MCU也常配合IAP做远程维护。我自己做IAP的体会是不要把IAP当成“加一个功能”它本质上是在设计一个“最小引导系统”。要考虑升级失败时的兜底策略否则设备很可能变成砖。这个第4部分细讲。4. IAP核心实操以STM32为例写一个最简单的Bootloader讲概念不实操都是耍流氓。这一节带大家走一遍最简IAP固件升级流程以STM32F103为例。GD32、HC32等国产芯片寄存器配置会有差异但思路完全一致学会一套能迁移到很多平台上。4.1 第一步规划Flash分区IAP的第一件事是给Flash做分区。以STM32F103C8T6为例它只有64KB Flash地址范围0x08000000到0x0800FFFF。要把这块空间分成两个区Boot区放引导程序App区放真正的应用。我常用的分法Boot区分配16KB地址0x08000000到0x08003FFFApp区分配剩下的48KB从0x08004000开始。为什么Boot要16KB如果Boot里只做串口接收和Flash写入这个大小足够但以后想加加密、日志存储、升级失败回滚16KB还能容纳。App的起始地址必须按Flash页对齐STM32F103的Flash页大小是1KB0x08004000刚好对齐没问题。App编译时有一件关键的事在工程里把链接地址改成0x08004000中断向量表偏移也要设置。否则编译出来的App仍认为自己从0x08000000开始跳过去必然乱套。在Keil里就是修改Target选项卡的IROM1起始地址和大小在IAR里改链接配置同时代码中通过SCB-VTOR重映射中断向量表。4.2 第二步Boot怎么判断是否需要升级Boot上电第一件事检查“升级标志”。这个标志可以放在Flash固定地址、备份寄存器里甚至外部引脚电平上。最简方案在Flash某个固定地址比如0x08003F00位于Boot区内部存一个固定值比如0xA5A5A5A5表示“收到新固件需要升级”。没有这个标志Boot直接跳转App。升级标志怎么产生App收到升级指令后先写标志到Flash然后软复位。复位后Boot看到标志进入升级模式等待接收新固件。接收方式先用最简单的串口约定帧头、命令、起始地址、长度、数据每包数据带CRC32校验。收到完整固件并校验通过后写入App区清除标志软复位跳转App。整个流程串起来是这样一个链路设备正常运行App→App收到升级指令→写入升级标志→软复位→Boot启动发现标志→进入升级模式→串口接收固件→校验→写入App区→清除标志→软复位→Boot无标志→跳转App→新版固件开始运行。4.3 第三步从Boot跳转到App的三个关键细节跳转是IAP里最容易出问题的环节。千万别写一句“跳到一个函数地址”就完事必须处理三件事切换栈指针、重映射中断向量表、确认跳转目标地址有效。栈指针App向量表的第一个字是初始栈顶地址也就是MSP初始值。跳转前先把App区起始地址处的第一个字读出来赋给MSP。向量表第二个字是复位向量把它当成函数指针跳过去。中断向量表重映射Cortex-M3/M4通过设置SCB-VTOR寄存器让中断表指向App区。跳转目标有效判断检查App区首字是否落在SRAM地址范围第二个字是否是合法的Flash地址防止跳到空白区域。typedef void (*JumpFunc)(void); void JumpToApp(uint32_t appAddr) { uint32_t spVal *(volatile uint32_t *)appAddr; uint32_t pcVal *(volatile uint32_t *)(appAddr 4); if ((spVal 0xFFF00000) 0x20000000) { // 关闭全局中断避免跳转过程被中断打扰 __disable_irq(); SCB-VTOR appAddr; __set_MSP(spVal); ((JumpFunc)pcVal)(); } }注意某些系列芯片强制设置VTOR可能需要先关闭全局中断而GD32F103的写法与STM32F103基本一致。我写代码时习惯用0x20000000判断栈地址是否落在SRAM区这个检查能挡掉很多“跳转到空白Flash”的坑。如果你要做在线调试下的跳转还要考虑调试器的干扰不过那属于进阶内容了。4.4 第四步App端要配合做什么App不是被动地被跳转进来的它要主动配合。第一中断服务函数要正常工作一进main就要重新设置SCB-VTOR为App的起始地址0x08004000。哪怕Boot跳转前设置过了App里再设一次也是保险做法因为有些库函数会动到这个寄存器。第二App收到升级指令后要有明确的处理逻辑确认升级意图、上报当前版本、请求下发固件。第三内存布局上如果App使用了Flash末尾区域做参数存储要认真规划避免覆盖Boot区或者升级过程要写的临时区。还有一个必须强调的点升级过程不能中途断电。最稳妥做法是接收数据时先写到临时缓冲区或另一个Flash区域全部接收完并校验通过后再一次性擦写目标区。当然这对Flash空间有要求如果芯片Flash很紧张只能边接收边写那就要在协议层做强化的断点续传和重传机制。我把这个原则叫做“要么不写要么写完整”IAP翻车大多翻在这里。5. 常见问题与排查技巧实录这一节分享一些我实际踩过的坑每一条都有真金白银的代价也顺便覆盖几个大家经常在群里问的问题。5.1 芯片连不上烧录器先查这5个地方供电目标板要独立供电调试器的3.3V通常只是电平参考电流能力很弱别指望靠它带动整板。BOOT引脚用串口ISP时BOOT0必须拉高下载完记得拉回否则设备永远进不了App。SWD引脚被复用程序里如果把SWDIO、SWCLK对应的引脚本用了烧录时连不上。解决办法是按住复位键再点下载或者在程序里用串口ISP先擦除芯片。接线距离SWD时钟线太长线上寄生电容会导致高频率握手失败适当降速或者缩短杜邦线。芯片被读保护锁死程序开了读保护调试器连上后无法正常操作可以先全擦除部分芯片需要配合工具解锁。这个操作要谨慎会把Flash内容全部清掉。5.2 STC ISP联机弹窗怎么处理STC的老用户都懂stc-isp下载软件联机时偶尔弹广告窗口非常影响产线操作节奏。处理思路很简单选一个自己用惯的稳定版本别一味追新下载过程中弹窗不要急着关等下载完成再用任务管理器关掉。另外STC部分新芯片必须用新版软件才支持旧版根本不认所以“关弹窗”这件事要根据芯片型号权衡。真到了量产环境我更推荐用脱机烧录器干净利落彻底远离这些杂七杂八的弹窗问题。5.3 IAP跳转后程序跑飞跑飞的原因几乎逃不出三个中断向量表没重映射、栈指针设置错误、App链接地址与实际存放地址不一致。排查方法比较机械先在Boot跳转前把App区的头四个字打印出来确认栈地址和复位向量对不对再用LED翻转来验证是否进入App主循环最后用一个定时器中断验证VTOR是否生效。如果跳转后一打开某个中断就死机九成是VTOR没设对。这个排查顺序我用了很多年很管用。5.4 Boot里定义的全局变量复位后到底会不会保留这个问题常有人问我认真答一下。Boot和App本质上是两个独立工程被编译成两个独立固件。Boot的全局变量在Boot复位后由启动代码统一清零或初始化数值不会保留。如果希望Boot和App之间传递信息比如升级标志、错误码应该把数据存到备份寄存器、Flash特定区域或者固定在RAM中的某个不被启动代码清零的地址段。一句话总结普通全局变量复位后不会保留跨区通信不能用普通变量实现。5.5 GD32、HC32等国产芯片做IAP的差异GD32F103和STM32F103硬件兼容性很好IAP思路一致但Flash擦写时序、中断向量表偏移的寄存器在某些型号上略有区别。HC32L136这种低功耗MCUFlash分区和BOOT引脚配置要看对应参考手册。我的建议是不管用哪家芯片先看用户手册里的“系统存储器”和“Flash编程”两个章节对照着手册写Bootloader比从网上抄代码靠谱得多。国产芯片厂商的寄存器习惯各成一家底层这些坑只能靠手册和数据手册自己趟。6. 烧录相关的几个实战心得文章写到这里我估计大家最想知道的是“我该优先掌握哪一种”。我的建议是新手先从ICP开始把Keil、MDK的下载调试搞得明明白白因为调试能力是基本功然后用ISP走一遍串口下载你会真正理解Bootloader的价值等要做产品化了再深入学IAP把内存布局、跳转、升级协议这套东西吃透。这条路我走过回头看是最流畅的学习顺序。还有两件事想提醒大家。第一量产烧录前一定要规划好烧录工装包括测试点、串口座、探针夹具这些直接影响产线效率。第二不管用哪种烧录方式工程要做好备份和版本管理固件文件名里带上版本号、日期、校验值。烧录环节看起来不起眼但它一旦出问题往往是整批产品的问题。把流程钉死比任何高级技巧都重要。最后如果手里正在做需要远程升级的设备一个最实在的小建议第一次做IAP时在开发板上把“老固件升级到新固件”和“新固件回滚到老固件”两个方向都测一遍确认双向都能成功再进产线。我因为只测了单向升级结果现场回滚失败连夜出差修过一次。这种经验写多少字都换不来。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑