ARTICLE DETAIL

资讯详情

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

芯片烧录方式解析:ISP、ICP与IAP的区别及选择指南

芯片烧录方式解析:ISP、ICP与IAP的区别及选择指南 芯片烧录这个词做嵌入式的几乎天天挂嘴边可一旦被问到ISP、ICP、IAP到底有什么区别能一句话讲清的人真不多。我刚开始那会儿也搞混过一度以为买了J-Link就能通吃所有芯片后来换了STC才知道有串口下载这回事再后来做量产产品发现最头疼的其实是IAP在线升级。这篇文章就按我这些年折腾下来的理解把几种烧录方式掰开揉碎讲一讲。不管你是刚入门的新手还是已经做了段时间但概念还有点模糊的工程师看完应该能建立一套清晰的判断框架什么时候用哪种方式、每种方式背后依赖什么硬件和软件、实操中最大的坑都在哪里。1. 芯片烧录到底在烧什么1.1 烧录的本质把程序写进芯片的记忆体先从最底层聊起。芯片本身只是一堆硅片上的逻辑电路CPU、RAM、GPIO这些外设全都摆在那但上电之后该干什么需要一个剧本来指挥。这个剧本就是我们写的固件编译之后是电脑上的.hex、.bin或者.elf文件。里面装的其实是一系列机器码指令告诉CPU从哪里取数据、做什么运算、往哪个寄存器写值。烧录这个动作本质上是把固件文件里的二进制内容通过某种物理接口SWD、UART、SPI、I2C等写入芯片内部的非易失性存储器。所谓非易失就是断电之后数据不会丢下次上电还能原封不动地取出来执行。这跟RAM完全不同RAM一断电就全部清零只适合临时存放运行中的变量。很多新手第一次用Keil下载STM32程序看到芯片跑起来了就以为程序存进芯片了。其实你下载的那个动作多数情况下就是烧到了Flash。但如果有人用了Download to RAM调试模式程序就只存在RAM里一断电就没了重新上电芯片还是空白。这个区别看似简单却能解释很多为什么我断电后程序丢了的求助帖。1.2 闪存、EEPROM、OTP烧录目标的区别既然烧录的目标是存储器那就必须先认识几种常见的存储介质不然后面讲ISP、IAP时会想不明白。Flash是现在绝大多数MCU内置的主力存储容量从几KB到几MB都有。它的特点是按扇区或页擦除写入前必须先把目标区域擦成0xFF然后才能写入有效值。擦和写是两个独立的操作擦除是按块、写入可以按字或按页这个特性直接决定了IAP升级时先擦后写的流程设计。STM32F103系列是1KB一个扇区GD32、HC32等国产芯片也大同小异但不同型号的分区大小差别很大做IAP前一定要翻手册查扇区映射表。EEPROM是电可擦除可编程存储器特点是按字节读写灵活性比Flash好。很多芯片内部会集成一小块EEPROM用来存校准参数、设备序列号、配置项也可以用外挂的AT24C02这类独立EEPROM芯片。OTP则是一次性可编程存储器写进去就改不了常见于遥控器、玩具、低成本专用IC里。如果确认产品固件永远不会升级选OTP芯片能省成本但一旦要改程序就只能换芯片所以选型时要掂量清楚。了解这些之后你会发现所谓的ISP、ICP、IAP本质上就是往Flash里写程序的三种不同途径。它们之间的差异说到底来自芯片厂商对谁有权写Flash的不同设计思路。1.3 为什么烧录方式比想象中复杂有人可能觉得烧录不就是把文件复制过去吗真正动手做过一轮就明白事情远没有这么简单。芯片的Flash写入是有严格时序的需要往特定寄存器里写解锁序列、等待忙标志位、处理擦写错误而且Flash本身有寿命反复擦写会损耗。这些底层操作通常由芯片厂商提供的驱动库或者烧录工具来完成我们不一定直接面对寄存器但必须理解背后的逻辑否则遇到烧录失败校验不一致时会无从下手。另外烧录还牵扯到启动模式、读保护、选项字节、时钟配置等一系列问题。一个看似简单的烧录动作背后是芯片从硬件层到软件层的完整协作。这也是我写这篇文章的原因——把底层逻辑讲清楚你再去用各种下载器、各种上位机软件心里就有底了。2. 三大烧录方式ISP、ICP、IAP到底怎么分2.1 ICP开发调试最常用的外部工具烧录ICPIn-Circuit Programming在线编程。核心特征是芯片已经焊在板子上我们通过一个外部调试器下载器直接连到芯片的调试接口由调试器负责把程序写进Flash。最常见的组合是STM32配J-Link或ST-LinkGD32配DAP-LinkAVR配专门的ISP下载器。ARM内核MCU的ICP接口一般是SWD或JTAG。SWD只需要SWDIO、SWCLK两根信号线加GND、VCC引脚占用极少所以如今绝大多数调试场景都走SWD。JTAG引脚多、速度快适合对调试带宽要求高的场景但平时开发很少用到。STC那种串口下载严格说不是ICP它走的是后面的ISP路线。ICP的最大特点是需要外部工具介入而且芯片本身不执行任何用户程序只是被动地响应调试器的读写指令。整个擦除、写入、校验过程都由上位机软件Keil、IAR、STM32CubeProgrammer等控制。开发阶段几乎所有人都在用ICP因为它快、稳、支持单步调试和变量查看出了问题能直接在源代码里定位。但到了量产烧录环节ICP就有明显短板每块板子都得接调试器还要为它预留SWD接口这在防抄板或者PCB空间紧张的产品上并不友好。2.2 ISP靠芯片内置引导程序一根串口线就能搞定ISPIn-System Programming在系统编程。和ICP最大的不同是它不需要外部调试器而是依靠芯片出厂时内置的一段引导程序Bootloader来完成下载。具体流程是用户把芯片的UART、USB等接口接到电脑上位机软件发送特定的握手信号芯片进入出厂Bootloader模式然后Bootloader接收固件数据并自行写入Flash。整个过程芯片自己执行Flash擦写操作上位机只是传输数据和显示状态。最典型的就是STC单片机。STC芯片上电时会先检测某个引脚的电平状态比如P3.0/P3.1是否接地如果满足条件芯片就进入下载模式通过串口接收程序并写入Flash。电脑端用STC-ISP软件一根USB转TTL线就能烧录连调试器都不用买成本极低。这也是很多高校教学、DIY项目首选STC的原因——学习门槛低材料费便宜。STM32其实也支持ISP它出厂就带了一段Bootloader放在系统存储器里System Memory。要让芯片进入这个模式需要把BOOT0引脚拉高再复位上电然后通过串口或USB发送协议命令来下载。不过日常开发时很少有人用STM32的串口ISP因为过程比较繁琐而且下载速度远不如SWD。但在产线不加调试器、或者需要烧录即将出货的裸板时STM32的ISP模式依然是很实用的后备方案。ISP的优势非常突出硬件成本极低、不需要专用调试器、占用引脚少串口引脚复用即可所以很多成本敏感的产品量产时首选ISP。它的缺点是速度比SWD慢而且依赖芯片内部的出厂Bootloader。如果你在代码里把Bootloader的存储区域也给擦掉了芯片就会失去ISP能力只能靠ICP或IAP来恢复。2.3 IAP程序运行中更新自己OTA的底层技术IAPIn-Application Programming在应用编程。这是三种方式里最聪明的一种不需要外部工具也不需要专门进入某个模式而是芯片在运行用户程序的过程中通过自带的驱动代码对Flash进行擦除和写入操作从而实现固件更新。IAP的典型架构是把Flash分成两个逻辑区域一段存放Bootloader引导程序一段存放App用户应用。芯片上电后先执行BootloaderBootloader检查是否需要升级。判断条件可以是串口收到了特定命令、U盘插入了固件文件、云端下发了新版本甚至是某个GPIO被拉低。需要升级就接收新固件写入App区不需要就直接跳转执行App。App运行过程中如果收到升级指令也会跳回Bootloader再走一遍升级流程。这就是所有OTA远程升级技术的底层原理。产品在用户手里时不需要拆机、不需要连接调试器通过WiFi、4G、LoRa等通信方式把新固件下发到设备设备自己用IAP把代码更新掉。对量产产品来说IAP几乎是必备能力——出厂时装的是v1.0固件发现bug或者加功能总不能把几万台设备全召回返工吧。IAP的实现难点集中在几个地方Flash擦写时序的严谨处理、Bootloader和App之间的跳转细节、升级数据的校验机制、擦写过程中突然断电的容错方案。新手做IAP最容易忽略的是掉电风险只想着能写进去就行结果写一半断电芯片卡在擦除状态既不能跑App也不能正常升级直接变砖。成熟的方案一定会有双备份区或者回滚机制这部分后面细聊。2.4 一张对比表看清三种方式的取舍把三种方式放在一起差异一目了然维度ICPISPIAP全称In-Circuit ProgrammingIn-System ProgrammingIn-Application Programming是否需要外部工具需要调试器/下载器只需串口/USB线不需要程序自己写Flash谁执行Flash擦写调试器发送指令芯片被动响应芯片内置Bootloader主动执行用户程序自己执行主要使用场景开发调试、产线烧录低成本量产、教学实验产品的在线升级、OTA是否支持远程升级一般不行一般不行可以配合网络/无线协议典型例子STM32ST-Link、GD32DAPSTC串口下载、STM32 BOOT模式各类IoT设备、车机、智能硬件下载速度快SWD/JTAG较慢UART为主中等取决于通信接口这里要特别说明一个观点ICP、ISP、IAP并不是互斥的选项反而经常是同一个产品三个阶段各用各的方式。开发阶段用ICP调试生产阶段用ISP烧出厂固件产品联网后又靠IAP做OTA升级。理解它们的区别不是要你选一个最好的而是要知道自己在当前阶段需要哪种能力、怎么组合起来最高效。3. 从新手视角看实操三种方式怎么用、怎么选3.1 ISP实操以STC串口下载为例STC是最适合入门ISP体验的芯片因为整个下载流程简单、硬件便宜而且网上资料极多。硬件准备上你需要一块STC单片机开发板或者自己搭的最小系统板再加一根USB转TTL串口线。接线非常固定USB转TTL的TXD接芯片的RXDP3.0RXD接芯片的TXDP3.1然后共地GND接GND。不需要接外部时钟和复位电路STC内置RC振荡器和上电复位逻辑板子上甚至可以不焊晶振。软件上先去官网下载STC-ISP烧录软件。打开后第一步选择芯片型号千万不能选错选错了即使握手成功也会在解析文件时报错第二步选择串口号一般是COM3、COM4这种数字不确定的话可以在设备管理器里确认第三步打开编译好的.hex文件第四步点击下载/编程按钮此时软件进入等待状态。最关键的一步来了STC需要先点击下载再给芯片上电。也就是说软件处于等待握手状态后手动给目标板断电再重新上电芯片上电瞬间才会进入出厂Bootloader开始接收程序。这个顺序反了几乎必失败——芯片先上电早就跑用户程序了根本不会响应串口命令。我第一次用STC时就是因为没搞懂这个顺序反复失败了几十次才摸到规律。下载成功的标志是软件提示下载完成并显示校验通过。实操中要注意波特率不建议拉太高实测115200以内比较稳妥超过后失败率会明显上升目标板供电要稳定如果USB口供电能力弱下载时波形抖动会导致校验失败换一个独立供电的USB口或者加个稳压电容能改善杜邦线的长度和接触品质也很有影响劣质线材经常制造一些见鬼的随机故障。3.2 ICP实操以STM32ST-Link为例STM32配ST-Link是ICP最经典的组合也是我推荐新手从零上手时用的方案。ST-Link V2售价很便宜兼容性极好ST官方支持到位Keil、IAR、STM32CubeProgrammer都能直接识别。接线按SWD方式SWDIO、SWCLK、GND三根线是必须的VCC可以接也可以不接。如果目标板自己供电调试器不接VCC也行但要注意必须共地否则信号参考电压不一致连接会随机失败。建议连接顺序是先GND再SWDIO/SWCLK最后VCC这样可以避免热插拔时产生过冲电压损坏引脚。软件上STM32CubeProgrammer是官方推荐的通用工具既能烧录也能配置读保护、选项字节等高级功能。如果日常在Keil里开发可以在Options for Target → Debug里选择ST-Link Debugger再在Flash Download页面勾选Reset and Run下载完成后芯片会自动复位运行省去每次手动按复位键的麻烦。ICP环境下的坑主要集中在SWD引脚被用户代码占用。PA13和PA14是SWD的专用引脚但很多新手在配置GPIO时把它们当普通IO用了代码一运行就把调试接口关闭下次下载直接连接失败。碰见这种情况常用的抢救手段是复位瞬间抢连按住板子的复位键点击下载在调试器开始连接的一瞬间松开复位键让芯片在运行用户代码之前先进入调试状态。这个招数在国产ARM芯片上同样适用。批量烧录场景STM32CubeProgrammer提供命令行模式。可以写一个简单的批处理脚本STM32_Programmer_CLI.exe -c portSWD modeUR -w firmware.hex -v前面是参数指定SWD接口和连接模式后面指定固件文件并做校验。产线用这种脚本配合夹具能做到一键、可记录的烧录比在GUI里逐个点按钮效率高太多。3.3 IAP实操双区Flash架构的搭建要点IAP方案搭建起来要动点脑筋但核心思路很固定Flash分区、Bootloader负责引导和升级、App负责业务逻辑、两者之间做好跳转。以STM32F103C8T6举例Flash容量64KB地址从0x08000000到0x0800FFFF。可以把Bootloader放在开头8KB0x08000000-0x08001FFFApp放在0x08002000及其之后这样简单直观也方便理解。如果你的芯片是F4系列Flash扇区大小不均匀前几个扇区可能是16KB、64KB、128KB那分区就必须按扇区边界对齐不能随意选个地址否则擦除时会误伤相邻代码。Bootloader的初始化逻辑比App简单得多初始化系统时钟、初始化串口或通信接口、检查升级标志、接收固件、写入Flash、完成校验、跳转。其中跳转的核心代码是设置MSP主堆栈指针和PC程序计数器typedef void (*pFunction)(void); #define APP_START_ADDR 0x08002000 void jump_to_application(void) { uint32_t app_stack *(volatile uint32_t *)APP_START_ADDR; pFunction app_reset (pFunction)(*(volatile uint32_t *)(APP_START_ADDR 4)); __disable_irq(); __set_MSP(app_stack); app_reset(); }原理是App程序的最开头存放着两个重要向量——第一个是应用程序的初始堆栈指针第二个是复位中断向量地址。跳转前从App起始地址读回这两个值设置好MSP然后跳转到复位向量App就相当于经历了一次上电启动。跳转前必须把全局中断关闭同时把Bootloader里初始化过的外设全部DeInit掉不然外设状态残留会让App初始化时出现冲突表现为串口乱码、定时器异常等疑难杂症。App工程这边要做两处修改。第一在链接脚本或编译选项里把程序的起始地址改为0x08002000这样编译出来的固件才能在烧写到App区后正确执行。第二在main函数最前面重新定位中断向量表SCB-VTOR 0x08002000;这一步极其重要。如果漏了VTOR重定位中断向量表还指向Flash开头而那里是Bootloader的区域一旦任何中断触发CPU会跳到错误地址程序轻则死机重则跑飞。我见过太多人做完IAP后发现下载完不跑断电后就坏了进不了中断查到最后都是这一行代码没写。升级数据的传输协议可以自己定义。最简单的一种Bootloader启动后等待2秒如果串口收到升级命令0xAA就进入升级模式接着按帧接收固件数据每帧包含长度、数据、校验值写完所有页之后对App区做一次CRC校验通过则跳转不通过则返回错误状态等待重传。实际产品里还可以加双备份区、断电标志位、版本号管理这些都属于IAP方案的高级玩法按需求逐层加就行。4. 烧录现场的高频问题与排查心得4.1 连接不上、下载失败的检查顺序烧录问题里90%都出在连接和识别环节。我总结了一个排查顺序按这个顺序走能最大程度节省时间。第一查接线。SWDIO和SWCLK有没有接反、GND有没有共地、杜邦线有没有接触不良。最简单可靠的办法是换一条线、重新插拔一次很多人排查到最后发现就是线材氧化了。第二查供电。调试器给目标板供电和目标板独立供电两者同时存在时容易产生电压差。建议明确供电来源开发板用USB或外部稳压供电调试器只接SWDIO、SWCLK、GND三根线不接VCC省去一堆麻烦。第三查引脚占用。如果芯片跑过一段把调试引脚复用掉的代码先进入复位抢连模式。不同调试器触发方式不同ST-Link可以在Keil里勾选Connect under resetJ-Link也能在J-Flash里配置连接模式为复位后连接。第四查下载器固件和驱动。ST-Link V2被某些软件降级过固件后Keil会提示ST-Link接不上升级官方固件工具能解决。J-Link则要留意它的盗版固件问题某些廉价山寨调试器在更新时容易刷成砖。第五查芯片状态。如果芯片被设置了读保护RDP级别1普通下载器可能读不了Flash。用STM32CubeProgrammer选Remove protection或者用ST-Link修改Option Bytes把读保护等级降回0即可恢复。4.2 烧录成功后程序不跑从哪查起程序明明下载成功了但芯片一点反应都没有这类问题排查起来要按顺序缩小范围。先检查复位策略。Keil里没有勾选Reset and Run时下载完芯片停留在调试模式下拔掉调试器后没有复位动作程序自然不会跑。解决办法很简单勾选那个选项或者下载完成后手动按一次复位键。再检查启动模式。STM32的BOOT0引脚如果被拉高芯片会启动到系统存储器模式你烧录的固件根本不会被执行。量一下BOOT0的电平正常应为低电平。很多自制板子在BOOT0上漏焊了下拉电阻或者接法不对就会导致这种烧录成功但跑不起来的诡异问题。接着检查时钟配置。如果你的固件配置成使用外部高速晶振HSE但板子上没焊晶振或者晶振起振失败芯片会一直卡在等待时钟就绪的循环里所有代码都不执行。解决方案是改回内部HSI时钟或者检查晶振负载电容是否匹配、焊接是否可靠。最后检查看门狗和低功耗设置。有些固件把看门狗喂狗操作放在了某个中断里如果中断配置有问题芯片会不断复位。低功耗模式下芯片进入睡眠后没有唤醒源也会表现成死机。排查这类问题有一个通用技巧把无关功能全部注释掉只保留串口打印和LED翻转跑通之后再一项项加回来二分定位非常高效。4.3 IAP升级失败的几个隐蔽坑IAP的坑比普通烧录深得多因为涉及双区跳转、Flash擦写时机、协议解析和掉电恢复任何一个环节出问题都会表现为升级后设备变砖。第一个坑是App起始地址没有对齐扇区边界。STM32F1系列按1KB扇区分区对齐比较轻松F4系列扇区大小不均匀如果App地址没有落在扇区分界线上擦除时会连带Bootloader的扇区一起擦掉。设计IAP方案前第一件事就是查芯片手册里的Flash扇区映射表把App起始地址设计在扇区边界上。第二个坑是跳转前没有关闭外设和中断。Bootloader里初始化过的串口、定时器、DMA在跳转进App后还保留着中断请求和缓冲区状态App的初始化代码很可能因此卡死或者串口数据错乱。正确做法是跳转前调用DeInit函数把用过的外设恢复到复位状态再关闭全局中断跳转成功后在App的SystemInit里重新初始化。第三个坑是升级过程缺少校验。很多写完不能跑的案例根源就是通信传输中丢了几个字节而代码没有检测出来。我自己的方案是每帧数据带CRC或者累加和校验整包写完后再对整个App区做一次CRC校验全部通过才允许跳转。哪怕只是做一个简单的逐字节累加和也能拦截掉绝大部分问题。第四个坑是写Flash期间断电。写Flash需要先擦除再编程擦除会持续一段时间在这期间断电Flash可能停留在半擦除状态。下次上电时这个扇区里的内容既不是旧程序的完整代码也不是新固件的数据芯片无法执行非法指令表现得就像彻底变砖。应对方案是引入升级标志机制升级前在某个固定位置比如Flash末尾或EEPROM里写入升级中标志升级成功后清除下次上电先检查标志如果标志存在且App校验不通过自动进入强制升级模式重新接收固件。这套机制看起来简单却是量产IAP方案里必不可少的安全网。5. 别被同名缩写搞迷糊ISP在图像处理里是另一回事5.1 图像信号处理器ISP的另一个身份如果你搜isp pipeline、isp图像处理这些词注意了——这里的ISP和芯片烧录完全不是一回事。图像处理领域里的ISP全称是Image Signal Processor图像信号处理器负责把CMOS或CCD传感器输出的RAW原始数据转换成我们肉眼看到的高质量RGB或YUV图像。这个处理流程是一个完整的pipeline首先是坏点矫正和黑电平校正去除传感器本身的固定噪声然后是去马赛克把拜耳阵列的单色像素插值成彩色再往后是白平衡、色彩校正、降噪、锐化、曝光控制等一系列算法。现在手机、行车记录仪、安防摄像头、工业相机里都有专门的ISP硬件模块像瑞芯微、富瀚微等方案里都集成了ISP能力。搞嵌入式的朋友可能会在同一个项目里同时遇到这两件事一方面要给主控芯片烧录程序另一方面要调试摄像头模组的ISP参数。所以看到ISP这个词时一定要根据上下文判断它到底指烧录还是图像信号处理别把两个完全不同的概念混在一起。我自己就见过技术讨论时两个工程师各说各的、吵了半天才发现讲的是两个ISP的场面。5.2 FPGA、脱机烧录与量产场景的补充搜索热词里还有fpga isp这个语境下的ISP通常指FPGA的在线配置方式。FPGA本身没有内部Flash配置数据bitstream一般存放在外挂的SPI Flash里上电时通过配置引脚加载到FPGA内部SRAM。很多FPGA也支持在线更新原理类似MCU的IAP先运行一段引导逻辑通过JTAG、SPI、网络或者串口接收新的bitstream写入SPI Flash然后触发重新配置。再补充一个量产场景的名词脱机烧录器也叫离线编程器。它的特点是不需要连接电脑提前把固件文件存进烧录器内部存储到了产线后夹上探针、按一下按键几秒钟就完成一块板子的烧录和校验。脱机烧录器还支持统计烧录结果和良率方便生产管理。如果你的产品要量产上千片强烈建议在打样阶段就确认好采用的烧录方式——到底是ICP配夹具还是ISP走串口还是购买脱机烧录器。这些决定会影响PCB上预留哪些接口、产线的工装设计甚至影响整条产线的节拍越早定越好。我个人在实际项目中的体会是判断一个固件方案用哪种烧录方式不需要背理论只需要问清楚三个问题产品需不需要产线批量烧录需不需要出厂后的远程升级开发调试时方不方便插调试器这三个答案出来方案基本就定了。如果容我多说一句经验量产产品再省成本也不要砍掉IAP的掉电保护和固件校验那部分投入换来的稳定性和售后成本节省远比省下的那几毛钱Flash空间值钱。
返回列表