前言:在上一篇文章中介绍了FPGA MultiBoot远程升级的核心原理。实际工程中发现,即便Golden与MultiBoot工程都开启看门狗,业务M镜像损坏后仍有可能无法回退到G镜像。远程升级过程中M镜像会被擦除改写,或出现非法指令,使FPGA配置停滞,内嵌于M镜像的看门狗配置也随之丢失。为实现异常场景下看门狗超时可靠回退,本文介绍一种Flash存储屏障方案。1、 概 述
以下错误条件均可触发启动回退:
- CRC 校验错误;IDCODE 器件编码错误;看门狗定时器超时错误。
要实现一套可靠的在系统升级(in‑system update)方案,必须保证存放在Flash中的黄金镜像 (golden image)始终处于写保护状态,仅允许对升级镜像 (update image)进行修改。
在MultiBoot多镜像启动过程中,黄金比特流 (golden bitstream)内部嵌入的IPROG命令,触发跳转到WBSTAR寄存器所指定的存储地址;随后FPGA配置逻辑开始搜寻下一个同步字(SYNC word),准备加载比特流。一旦检测到有效SYNC同步字,配置逻辑就接收同步字后续的配置命令与数据,完成FPGA器件配置。倘若next_config_addr位置不存在升级镜像,或者升级镜像中的SYNC同步字已经损坏,配置逻辑会遍历扫描整片Flash存储器,试图寻找一个有效的SYNC同步字。
针对串行Flash中升级镜像区域损坏这类故障场景,必须配置硬件看门狗定时器,以此触发回退,切回黄金镜像分区。2、 看门狗定时器配置 一种实现方式是在黄金镜像和升级镜像的比特流中,使用BITSTREAM.CONFIG.TIMER_CFG属性,将看门狗定时值嵌入到比特流内部。在黄金镜像、升级镜像对应的XDC约束文件中设置该比特流定时器属性,如下属性设置:
set_property BITSTREAM.CONFIG.TIMER_CFG [current_design]
在7系列FPGA中,配置看门狗定时器,使用专用内部时钟CFGMCLK的分频时钟作为计时时钟。定时器的计数值,必须足够覆盖从开始配置直到器件启动完成的全部耗时。启动阶段因DCI匹配、MMCM锁相、DONE信号拉高所产生的所有等待时间,也都要一并纳入计时预算。因此,需要结合以上各项条件仔细计算,才能得到正确的定时器数值。本文提供另一种实现方案:使用独立的屏障镜像(barrier-timer-image),替代通过比特流属性开启看门狗定时器的方式。
使用屏障-定时器镜像,不再需要为TIMER_CFG比特流属性去计算定时器计数值。参考设计附带的Tcl脚本,可用于生成屏障镜像以及地址映射表,用来将屏障镜像、黄金镜像、升级镜像统一排布到Flash存储器中。在MultiBoot工程中实现定时器镜像所用到的 Flash 存储分区结构与加载步骤,如图1所示。
图1、MultiBoot、故障回退与屏障镜像的Flash存储分区及配置加载步骤重要提示:必须保证SPI Flash中的黄金镜像 (golden)、timer1、timer2 分区始终处于安全受保护状态,仅允许对升级镜像 (update image) 分区执行修改操作。图1 所描述的、采用屏障镜像的设计实现基本流程如下:
1、FPGA配置逻辑,开始执行存放在Flash地址0处的黄金比特流内部命令。黄金比特流中内置的IPROG命令,发起跳转,跳转到WBSTAR寄存器中保存的目标地址。在本示例中,WBSTAR寄存器指向timer1屏障镜像的起始地址。
2、位于升级镜像之前的timer1(屏障镜像)会开启一个短超时看门狗。它协助配置逻辑锁定到真正有效的SYNC同步字,降低因升级镜像损坏而产生假同步 (false sync)的风险。
3、a. 在timer1之后存在完好可用的升级镜像:升级镜像正常加载。
b.升级镜像头部损坏,或者扇区被擦除,也就是升级镜像起始位置找不到SYNC同步字(AA995566):FPGA配置逻辑只有识别到SYNC同步字(AA995566)之后,才会开始解析比特流内容。一旦SYNC同步字损坏或者被擦除,配置逻辑会忽略读到的所有数据与命令,并持续扫描 Flash,试图寻找有效的SYNC同步字。在该场景下,timer1中设置的定时值会触发看门狗超时错误,执行回退Fallback,加载故障安全镜像(即黄金镜像golden image)(跳转到第 5 步)。
4、a.如果timer1之后加载到完好可用的升级镜像,则timer2会被硬件忽略,不再起作用。
b.升级镜像后半部分损坏,或者末尾扇区被擦除:在这种情况下,配置逻辑无法收到启动结束标记,不能完成完整配置流程。此时timer2生效,看门狗超时错误触发回退,跳转到Flash地址 0,也就是黄金镜像的存储位置。
5、看门狗超时错误触发回退(Fallback),器件加载作为故障安全备份的黄金镜像。
3、 屏障镜像组成
通过脚本生成的屏障(定时器)镜像,是一组配置命令集合,用于同步FPGA配置逻辑,并设置配置看门狗定时器计数值。表1列出了屏障镜像内部用来使能TIMER寄存器的基础配置命令。
表1、屏障镜像的内部组成
生成地址表与屏障镜像的Tcl脚本下载的xapp1247‑multiboot‑spi.zip压缩参考包中,提供了Tcl 脚本multiboot_address_table.tcl。
生成地址表和屏障镜像的操作步骤:
(1)将参考设计压缩包解压至本地某个目录;
(2)打开 Vivado 命令行终端,切换工作目录到参考设计中脚本所在路径;参考设计目录下存在multiboot_address_table文件夹,里面存放multiboot_address_table.tcl脚本。
使用如下语法运行该脚本:
>> tclsh multiboot_address_table.tcl <flash_type> <data_width> <freq_mhz>< flash_size_mbit> <bitstream_size>
参数说明:
flash_type:经过验证支持的 Flash 类型:spi、bpidata_width:Flash 数据位宽,可选值:1、2、4、16freq_mhz:CCLK 配置时钟频率,等于工程中ConfigRate配置速率参数flash_size_mbit:Flash 器件容量,单位:兆比特 (Mb)bitstream_size:比特流大小,单位:字节 (Byte)
注意:比特流大小可查阅UG470 获取。如果开启了比特流压缩,需要输入压缩后的比特流文件大小。请注意:开启压缩后,每一次工程重新综合实现,bit 文件的大小都可能发生较大变化,此时需要重新运行本 Tcl 脚本。
运行该Tcl脚本之后,会生成两个定时器镜像文件:timer1、timer2。输出文件保存在脚本的运行工作目录下。脚本同时输出Flash地址映射信息,指明各个文件在串行Flash中的存放位置,还会直接给出write_cfgmem命令,用于将四份文件拼接合并。下面是在Windows命令提示符下执行脚本后的一段示例输出。
c:xapp1247multiboot_address_table>tclsh multiboot_address_table.tcl spi 1 3 12 81132000Flash type : SPIFlash width (bits) : 1CCLK frequency (MHz) : 3Flash density (Mbits) : 128Bitstream size (B) : 1132000Writing Timer: timer1.binWriting Timer: timer2.binGolden bitstream address : 0x00000000Timer1 image address : 0x0013FC00Multiboot image address : 0x00140000Timer2 image address : 0x00280000write_cfgmem command:write_cfgmem -format mcs -size 16 -interface SPIx1 -loadbit “up 0x00000000up 0x00140000“ -loaddata “up 0x0013FC00 timer1.bin up 0x00280000timer2.bin“
在黄金镜像工程实现阶段,务必保证NEXT_CONFIG_ADDR配置项指向运行脚本后输出的timer1镜像起始地址。例如,以上一页给出的地址映射样例为例,通过比特流属性NEXT_CONFIG_ADDR进行设置,使黄金镜像的WBSTAR寄存器保存值为0x0013FC00:
set_property BITSTREAM.CONFIG.NEXT_CONFIG_ADDR 0x0013FC00 [current_design]
升级镜像工程中用于开启 MultiBoot 功能的约束保持不变。
在脚本输出示例中需要留意:write_cfgmem命令对timer1、timer2的.bin屏障二进制文件使用‑loaddata参数;对golden、update的.bit比特流文件使用‑loadbit参数。生成串行Flash烧录文件时,务必严格保证各个文件对应的起始地址顺序正确。
在Vivado工具中可以使用-help 命令,查看write_cfgmem各个命令选项的详细说明。
write_cfgmem -help
在后续文章中,我们将通过一个设计示例介绍如何可靠实现FPGA远程升级,欢迎关注公众号后续系列文章。
159