资讯中心

FPGA远程升级双保险:MultiBoot回退与看门狗机制详解

📅 2026/10/2 5:44:16
FPGA远程升级双保险:MultiBoot回退与看门狗机制详解
先说一个真实场景。设备已经在现场跑了快三年某天夜里远程推送一个新版本上位机反馈“升级成功”。第二天现场打电话过来说整台设备直接罢工你远程一查FPGA根本没有加载日志里只有一行孤零零的配置失败。这种事故在FPGA远程升级里太常见了根子往往不在网络也不在Flash而是当初设计固件时压根没想过“改错了怎么把自己救回来”。Xilinx的MultiBoot加上一颗不起眼的外部看门狗就是干这个用的MultiBoot解决“配置文件加载阶段失败”的回退看门狗解决“镜像能加载但系统跑不起来”的死锁两条故障路径都有兜底才敢叫双保险。远程升级不是只在实验室里来回烧写几个bin它要面对真实环境里的断电、误码、Flash擦写半途而废、新镜像引入致命逻辑bug。这篇文章我会把MultiBoot的跳转与回退机制、看门狗与FPGA之间的时序配合、QSPI分区和实际驱动代码全部拆开讲一遍最后再总结我在现场排查过的几个典型翻车场景。适合正在做FPGA远程升级、被回退失效问题折磨过、或者准备把Zynq和7系列设备推上产线的工程师参考。1. 为什么远程升级总怕“变砖”按故障阶段分清楚两道保险的职责1.1 一次远程升级可能栽在三个环节把一次完整的远程升级拆开看大致要经过文件传输、Flash写入、镜像切换三个环节。传输环节出错的概率其实最低因为以太网、串口、CAN这类链路通常都有校验文件坏了重传就是。真正的风险在后两个环节。Flash写入期间一旦断电擦除一半的扇区会让目标镜像区处于残缺状态而镜像切换时如果新bitstream的配置属性、引脚约束或逻辑本身有问题FPGA可能连配置都完不成或者配置完成后系统直接挂死。以我见过的一个案例来说有位同事在Zynq上做FPGA升级升级前没在意Flash分区的扇区对齐把新镜像的起始地址放到了某个64KB扇区的中间。结果写入时每次擦除都会殃及相邻区域升级后有一定概率整个Flash内容被破坏连最原始的版本都找不回来。这就是典型的第二环节问题。1.2 两类故障对应两道独立的保险很多人把MultiBoot和看门狗当成一回事其实它们覆盖的故障阶段完全不同。MultiBoot解决的是配置加载失败。加载update镜像过程中如果CRC校验不过、同步字找不到、DONE引脚没有按预期拉高配置逻辑会自动回退到Golden Image的地址重新开始配置。看门狗解决的是运行态异常。镜像已经成功配置DONE也拉高了但内部的业务逻辑就是跑不起来比如状态机死锁、DDR训练不过、外设总线挂死、PCIe链路起不来。此时FPGA自己的配置机制早已结束MultiBoot的回退条件不再触发唯一的补救办法就是外部看门狗超时强制复位整个系统让它重新从Golden启动。这两道保险合起来覆盖的是“加载失败”和“运行失败”两条完全不同的故障路径。只做MultiBoot不做看门狗新镜像逻辑有bug时照样会卡死只做看门狗不做MultiBootFlash里的update镜像损坏时狗把系统复位多少次都还是加载同一个坏镜像。所以标题里“双保险”这三个字不是营销话术是实际工程里缺一不可的配置。1.3 哪些场合必须认真对待这套组合如果设备是可远程访问、无人值守、批量部署的双保险基本是硬性要求。电网终端、通信基站板卡、车载域控、工业网关、卫星载荷都有类似的场景升级失败后现场不一定会有人带着JTAG过去救砖唯一的正确路径就是让设备自己恢复。反过来如果产品只在实验室用、随时能烧写、升级窗口完全可控那MultiBoot可以不做看门狗也可以省。但一个产品只要过了样机阶段、开始批量出货省掉这两道保险的代价就会在某个深夜变成紧急电话。我觉得一个很现实的原则是升级失败后如果恢复动作需要“人到现场”那么这套双保险就很有必要。恢复动作如果只是“重新上电/重新配置”就能完成那么设计目标就是让设备每次上电都自动回到可运行状态。2. MultiBoot回退细节从同步头识别到IPROG跳转的执行链路2.1 Golden Image与Update Image的分工MultiBoot方案里至少有两个镜像Golden Image和Update Image。Golden Image存放在Flash的低地址区一般从0x0开始。它的职责很纯粹足够小、足够稳、只做基础初始化和升级管理。等Update Image验证通过后Golden会跳转过去如果Update挂掉Golden还能兜底恢复设备。千万不要在Golden里堆太多业务功能镜像越小Flash擦写和回退时序越容易被控制。Update Image是实际的业务功能镜像存放在更高地址。日常升级时更新的都是它。稍微讲究一点的设计会在Update之外再预留一个Recent Image区把上一个稳定版本放那儿这样即使新版本有问题还能回退到上一版而不是只能回到纯引导的Golden。实际操作里Flash分区通常长这样地址范围示例分区作用0x000000 - 0x00FFFFGolden Image引导、升级管理、看门狗使能0x010000 - 0x0FFFFFUpdate Image当前业务版本0x100000 - 0x1FFFFFRecent Image可选上一个稳定版本0x200000 - 0x2FFFFF配置/标志区升级状态、版本号、校验值这个表只是参考实际偏移要按Flash容量和镜像大小重新算。关键原则是镜像区必须按Flash的最小可擦除块对齐通常是4KB、32KB或64KB不然擦除操作会波及邻居。2.2 配置引擎如何通过WBSTAR和IPROG完成跳转Xilinx FPGA配置引擎在加载bitstream时会顺序读取Flash内容匹配同步字然后解析配置数据。Multiboot的核心就是让配置引擎中途收到一条IPROG指令把“从当前Flash地址继续读”改成“从WBSTAR寄存器指定的地址继续读”。跳转动作本身不复杂大致是这样软件把目标地址写入WBSTAR寄存器。软件向CMD寄存器写入IPROG命令字0x0B。配置引擎停止当前流从WBSTAR指向的新地址重新开始扫描同步字并加载配置。加载成功则DONE拉高进入用户逻辑运行阶段。这里最容易出问题的就是WBSTAR的地址格式。有些资料的表述是“word address”有些是“byte address”不同芯片型号甚至不同配置接口对地址位宽的解析还不一样。我在Zynq上遇到过类似问题写错了地址不会立刻报错而是直接跳到一个Flash空白区配置引擎找不到同步字最后卡死。所以做这一步时不要想当然直接填Flash字节偏移去目标芯片的配置手册里把WBSTAR寄存器的位定义读清楚再写代码。比如7系列和Zynq的PCAP接口行为就有差异驱动API也不一样。2.3 Fallback回退的条件和局限MultiBoot真正救命的机制不是跳转本身而是跳转失败之后的Fallback回退。Fallback触发条件是配置加载失败典型场景包括同步字匹配不到、配置数据CRC错误、DONE超时未拉高。Xilinx 7系列和Zynq的配置逻辑在检测到这些错误后会把加载地址重新指向默认的Golden地址通常是0x0然后重新加载。但要让它生效必须在bitstream里显式启用。Vivado里对应的属性是BITSTREAM.CONFIG.CONFIGFALLBACK默认情况下这个功能是不开的。很多工程师做MultiBoot时只配置了跳转地址忽略了Fallback使能位结果update镜像坏了之后配置引擎不会回到Golden而是继续往Flash深处扫直到扫完整个Flash都找不到有效配置板子就死在那里。这个坑在Xilinx论坛上被反复问过问题标题直白点说就是“configuration logic is stuck and unable to fallback when multiboot image”。根因基本逃不出以下几点CONFIGFALLBACK没有设为ENABLEWBSTAR地址换算错误跳转目标地址并不是有效的镜像起始位置Flash总线宽度或配置模式与镜像头不匹配还要注意Fallback不是全能触发。如果IPROG指令本身已经成功执行但新地址区域确实存在一个“看起来有效但逻辑会挂死”的镜像那么配置引擎会认为加载成功DONE正常拉高Fallback机制不会介入。这就是为什么单一MultiBoot解决不了运行态故障必须再叠加看门狗。3. 外部看门狗怎么设计才不“乱咬”喂狗窗口、选型与复位拓扑3.1 为什么必须用外部看门狗而不是FPGA内部软狗很多做软件出身的人第一次听到“FPGA看门狗”会下意识想在逻辑里写一个计数器定期检查某个运行标志是否翻转。这种内部看门狗在镜像正常工作时有意义但注意它本身就是FPGA配置的一部分。一旦FPGA配置失败、配置到了半截、内部时钟域乱了内部看门狗也和业务逻辑一起失效根本不可能把设备拉回来。外部看门狗芯片独立供电、独立时钟、独立于FPGA配置存在它的复位输出直接接在FPGA的配置引脚或系统复位链路上只有它能在任何异常状态下维持“最后纪律”。选型上常见三类方案类型代表型号特点适合场景窗口式看门狗MAX6369系列喂狗信号必须在窗口内过早过晚都会复位对程序卡死检测比较严格的板卡单脉冲/机械式看门狗STWD100, SP706超时时间内只要WDI有翻转即可通用场景简单可靠可调/暂停式看门狗TPS3823, TPL5010窗口可配置部分支持暂停升级期间需要拉长窗口我个人的习惯是FPGA升级项目优先选窗口可调的看门狗并且尽量留出一个“升级模式”引脚。这样在固件传输和Flash写入期间可以把喂狗窗口临时拉长避免升级流程还没跑完就被强制复位。3.2 喂狗窗口设计正常态、升级态、低功耗态看门狗设计最容易“翻车”的地方就是喂狗策略。正常运行时喂狗周期设置为超时周期的三分之一到二分之一比较常见。比如看门狗超时5秒代码里每1到2秒喂一次狗留足余量。升级期间不能简单停止喂狗。如果你完全停掉看门狗会在升级流程中途把系统复位那升级永远完不成。比较稳妥的办法是分阶段处理传输接收阶段网络文件还没接收完此时喂狗不要停继续正常喂。Flash擦写阶段擦写一般有几十毫秒到几秒的不可中断窗口可以在进入擦写前暂停喂狗但不能让它超时太早。如果擦写超过看门狗超时就会被咬掉。校验与标志写入阶段同样建议继续喂狗直到FPGA发出IPROG跳转指令的前一刻。如果你用的是可暂停外部看门狗最简单的做法是整个升级过程中置高“升级模式”引脚让看门狗超时拉长到预计升级耗时的2到3倍给升级留足余量。升级完成后业务代码正常切换并恢复常规喂狗节奏。假如升级真的卡死超过升级模式窗口看门狗超时复位整个系统重新从Golden启动此时Golden里的升级管理器检查“升级未完成标志”可以自动重新尝试或者等待用户重新下发。因为看门狗已经被拉长过这套逻辑不会陷入“升级永远被中断”的循环反而能在真死锁时兜底。3.3 看门狗复位与FPGA配置的握手关系外部看门狗的复位输出接到哪个引脚直接影响恢复效果。对纯FPGA 7系列方案常见做法是把看门狗复位输出接到PROG_B引脚。PROG_B拉低后FPGA立即重新开始配置从Golden地址加载。这个方案简单粗暴不会影响PS侧软件状态适合FPGA逻辑跑飞、但板级其他芯片还正常的场景。对Zynq方案要看你想复位的是整个系统还是只复位PL。如果只复位PL可以接PROG_B如果希望PS和PL一起干净重启建议看门狗复位输出接到系统的电源复位或者PS的SRST引脚。这个选择很重要因为如果PS已经挂死、PL却还在正常工作只复位PL并不能解决问题。还有一个容易被忽略的细节FPGA配置过程需要一段时间如果看门狗超时时间比FPGA配置时间还短就会出现“上电后来不及喂狗就被复位”的反复重启现象。解决办法是选带“启动延时/初始窗口”的看门狗芯片或者用MCU配合在FPGA配置完成后再开始喂狗。我实际踩过的坑是选了一颗看门狗默认超时1秒而FPGA配置需要3秒。上电后FPGA还没配完狗先咬了复位再上电再咬LED一直在闪板子根本没机会正常工作。后来换成带初始窗口的型号把配置完成信号作为喂狗使能问题才消失。4. 工程落地QSPI分区、Vivado属性与跳转驱动代码4.1 QSPI分区设计和地址换算前面说过分区原则这里再往后走一步结合实际场景给个可参考的例子。假设板载QSPI Flash是16MBFPGA工程是Zynq-7020bitstream大小在3MB以内。分区设计可以这样定地址范围大小内容0x000000 - 0x00FFFF64KBGolden Image0x010000 - 0x3FFFFF约3.9MBUpdate Image0x400000 - 0x7FFFFF4MBRecent Image0x800000 - 0x7FFFFF?剩余升级标志、版本号、校验值注意要留出足够的余量因为FPGA工程后期越改越大镜像尺寸会膨胀。我见过不少人把Update分区画得很紧结果新版本只多了几个LUT和BRAM镜像大了200KB直接放不下只能重新调分区。地址换算这一步建议在代码里统一用字节地址存储只在调用驱动时按目标芯片要求做转换。比如有的寄存器要求字地址你就做右移有的直接填字节地址就不用动。换算逻辑最好封装成一个函数别散落在各处。4.2 Vivado里需要设置的bitstream属性配置工程时有两组属性必须检查。第一组是Fallback相关set_property BITSTREAM.CONFIG.CONFIGFALLBACK ENABLE [current_design]这个属性同时作用在Golden Image和Update Image上。放在Golden里是确保Golden自身加载失败时也能有个兜底放在Update里是确保Update加载失败时能回到Golden。记忆方法很简单每个镜像都要开Fallback才能形成回路。第二组是SPI配置模式相关set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]如果板子QSPI硬件连接是x4模式Golden和Update的SPI_BUSWIDTH要一致不然配置引擎切换地址后按错误的IO宽度读Flash会直接卡在同步字检测。这些属性可以在XDC约束里写也可以直接在Vivado的Settings界面配置。无论哪种方式最后都要看生成的bit属性是否正确用vivado的report_property或者直接查bin文件头都不难。4.3 SDK/裸机代码实现跳转Zynq的PCAP接口驱动在不同版本里API差别比较明显但从裸机角度理解核心操作无非两步写WBSTAR再写IPROG命令。老版本的Xil_In32/Xil_Out32照样能完成这套动作。#include xil_io.h #include xparameters.h /* 具体寄存器偏移以当前Vivado版本的XDevCfg头文件为准 */ #define DEVCFG_CTRL_OFFSET 0x00000004 #define DEVCFG_CMD_IPROG 0x0000000B #define DEVCFG_WBSTAR_OFFSET 0x00000008 void fpga_multiboot_jump(u32 byte_addr) { /* 1. 根据你的目标芯片手册确认是否需要对地址做格式转换 */ u32 wbstar_value byte_addr; /* 2. 写WBSTAR寄存器 */ Xil_Out32(XPAR_XDEVCFG_0_BASEADDR DEVCFG_WBSTAR_OFFSET, wbstar_value); /* 3. 下发IPROG命令 */ Xil_Out32(XPAR_XDEVCFG_0_BASEADDR DEVCFG_CTRL_OFFSET, DEVCFG_CMD_IPROG); /* 4. 正常情况函数不会返回若返回多半是PCAP状态异常 */ while (1) { /* 可在这里加日志或状态灯 */ } }写这段代码时寄存器偏移务必对照你用的Vivado版本生成的xdevcfg.h或xparameters.h不同版本命名可能不同甚至Vitis HLS裸机工程里路径也不一样。直接照搬网上旧工程的偏移很常见的结果是WBSTAR没写进去IPROG发了个寂寞。跳转之前还要做几个收尾动作把不必要的GPIO中断关掉把外设MAC、DMA、UART FIFO里残留数据清掉通知板上MCU或看门狗芯片进入“升级待完成”状态否则跳转后外设残留中断过来可能干扰新镜像初始化。4.4 Golden Image里的升级管理逻辑Golden Image除了能提供基础功能通常还要承担升级管理。我的做法是让它在启动后检查“升级标志区”的状态状态值含义Golden动作0x5A5A_0001正在升级检查Update是否完整完整则跳转0x5A5A_0002升级完成跳转Update0x5A5A_0003升级失败重新接收固件或等待用户操作0x00000000出厂默认跳转Update前提是Update已有可用镜像这套状态机的写法不难但很重要。它能让设备在升级中断电后上电时知道自己该从哪里继续而不是盲目跳到一个残缺镜像里傻等。5. 实测避坑回退失效、狗提前咬、掉电中断的排查思路5.1 配置卡死无法回退一条完整排查链路先描述现象Update镜像写入后执行IPROG跳转FPGA迟迟不拉高DONE也没有自动回到Golden设备彻底黑屏。这个问题我在论坛上见过不少类似求助英文标题基本就是“when configuration logic is stuck and unable to fallback when multiboot image”。我的排查习惯是按下边顺序走先确认CONFIGFALLBACK是否真的在bitstream里使能了。用文本方式打开bin文件或通过Vivado报出的属性确认两个镜像都设置了ENABLE。这一步最容易翻车很多人只在Update里设了Golden里忘掉。再查WBSTAR地址。用调试器读一下跳转前寄存器里的值和Update镜像实际存放地址对比。如果寄存器值是0x00001000而Update在0x010000那就是单位换算没做对。然后看Flash里目标地址处是否有正确的同步字0xAA995566。如果有示波器/逻辑分析仪抓一下配置时钟和Flash片选看配置引擎是否真的开始读目标区域。还要确认双方SPI总线宽度一致。一个x1一个x4跳过去后读到的是错位数据同步字当然匹配不上。最后检查Flash剩余空间和分区边界确认镜像没有被截断或跨区覆盖。按这个链路排查大部分回退失效问题都能定位。切忌一上来就怀疑硬件先把配置属性和地址换算查清楚再碰硬件。5.2 看门狗在配置期间提前触发启动时序要捋清第二个高频事故是看门狗“乱咬”。最典型的是上电时FPGA配置需要1到3秒而看门狗默认超时只有几百毫秒于是每次上电都陷入“配置未完成→狗复位→重新配置→狗又复位”的死循环。解决方向有三类换带启动延时的看门狗芯片让狗在上电后先等几百毫秒到几秒再开始计时用FPGA或MCU的“配置完成”信号作为喂狗使能配置完成前不喂配置完成后才开始喂外部看门狗本身支持“初始化窗口”配置调大到覆盖整个FPGA配置时间除上电阶段外升级阶段也可能“狗咬”。比如升级过程使用FTP传输大文件传输耗时5分钟但升级模式窗口只留了1分钟结果文件传一半狗就咬了。这个问题的检查思路是看门狗超时设置要cover住整个升级流程的预估时间并再加50%到100%余量。5.3 升级断电中断从标志位到恢复机制远程升级最怕的是擦写Flash期间掉电。Flash写入过程中掉电轻则update分区残缺重则整个文件系统损坏、分区表错乱。多分区设计能缓解一部分问题但要彻底恢复还得靠Golden里的恢复逻辑。升级开始时首先写“正在升级”标志。这个动作要放在Flash分区里避免和镜像区互相干扰。等新镜像接收完整、CRC校验通过、标志区更新为“升级完成”之后才允许跳转。这样即使掉电发生在上一个步骤下次上电Golden读到“正在升级”标志就知道上次升级被中断了可以主动清掉这个标志并选一个稳定版本启动避免反复尝试坏镜像。更进一步可以在标志区记录当前工作的版本号、上上次成功版本号和失败次数。连续多次升级失败后Golden自动回退到最老但确定能跑的版本而不是无限尝试。这套机制加进恢复逻辑后现场基本不再需要人工救砖。5.4 测试清单用“破坏性实验”验证双保险最后说说验证。我在测试MultiBoot看门狗时会在出厂前刻意做一轮“破坏性实验”模拟各种极端情况正常烧写Golden和Update上电后确认设备跑到Update手动改坏Update镜像的关键字节上电后确认自动回退到Golden在升级开始后立刻断电确认重新上电能恢复让Update镜像逻辑里故意写一个死循环确认看门狗超时后能强制复位回Golden反复执行100次升级与回退统计失败率确认Flash寿命和擦写时序没问题这些测试看起来耗时但能暴露很多只有真实故障时才会出现的时序问题。远程升级这种东西现场出一次事代价远超实验室里多测半天。我个人在这套方案上的体会是MultiBoot和看门狗本身都不是新东西难点全在细节的链路串联上。地址换算、Fallback使能、喂狗窗口、掉电恢复这些东西单独看都不难但一旦串起来任何一个环节想当然都会变成现场事故的源头。所以如果有条件尽量在实验室把上述破坏性测试跑完再考虑推到现场。

看完文章,想为自己的企业也做一次专业网站诊断?

尧图顾问免费为您评估现有网站,并给出建站/改版建议与报价方案。

免费获取方案