Xilinx Multiboot实例演示_碎碎思的博客-程序员秘密

技术标签: 接口  mapreduce  jwt  arm  嵌入式  

原理

关于Multiboot的原理参考《Xilinx 7系列FPGA Multiboot介绍-远程更新》,基本原理都在此文写的很清楚,本文主要从实例出发演示Multiboot。

补充

FPGA SPI闪存配置接口

图3显示了7系列FPGA和具有x1数据宽度的SPI闪存之间的基本连接。读取和地址指令通过主输出-从输入(MOSI)引脚从FPGA发送到SPI闪存。数据通过主输入从输出(MISO)引脚从SPI闪存返回。SCK是时钟引脚,SS是低电平从选择引脚。

参考:UG470

Vivado工具流程(Multiboot大致流程)

为Multiboot程序准备bit流

本节概述了为多引导应用程序创建和更新比特流所需的比特流属性。对于未指定的位流选项,请使用默认设置。

表1概述了用于生成和更新具有每个属性描述的位流的基本多引导位流属性。有关这些属性的详细说明,请参阅Vivado Design Suite用户指南:编程和调试(UG908)。

具体含义如下:

启用在配置尝试失败时加载默认位流

使用下一个配置映像的启动地址设置热启动启动启动地址(WBSTAR[28:0]位)寄存器

指定启用FPGA位流文件压缩

在Vivado中打开黄金设计实现(Golden)的约束文件(.xdc)。将以下内容复制粘贴到约束文件中,然后保存对.xdc文件所做的更改:

set_property BITSTREAM.CONFIG.CONFIGFALLBACK ENABLE [current_design]
set_property BITSTREAM.CONFIG.NEXT_CONFIG_ADDR 0x0400000 [current_design]
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 1 [current_design]

上述不理解没关系,后续实例会有使用教程。

接下来,可以在更新设计(将要更新的文件)中打开约束文件(.xdc),并将以下比特流属性添加到约束文件中,然后保存:

set_property BITSTREAM.CONFIG.CONFIGFALLBACK ENABLE [current_design]
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 1 [current_design]

注:默认情况下,SPI_BUS为x1,如果未使用默认x1模式,请确保设置此属性。

生成SPI闪存编程文件

具体查看《【Vivado那些事】Vivado两种生成、固化烧录文件》。

使用write_cfgmem Tcl命令创建闪存编程文件(.mcs)。

write_cfgmem获取FPGA位流(.bit)并生成可用于编程SPI闪存的闪存文件(.mcs)。

例如,生成包含两个FPGA位流(.bit文件)的闪存编程文件(.mcs)文件,如下所示:

write_cfgmem -format mcs -interface SPIX1 -size 16 -loadbit "up 0 <path>/golden.bit up
0x0400000 <path>/update.bit" <path>/filename.mcs

注:地址值0x0400000是参考设计中使用的示例。应使用黄金图像(更新图像的起始地址)中设置的Addr A1值(见表1)。

请参阅Vivado Design Suite用户指南:编程和调试(UG908或使用Vivado中的-help命令,以了解每个write_cfgmem命令选项的详细说明:

write_cfgmem -help

硬件验证

硬件验证其实很简单,我们分别建立两个工程,两个工程都是流水灯程序,分别从左到右和从右到左流水灯,这样可以很清楚知道FPGA运行了哪个程序。接下来破坏golden程序,按照上述制作MCS文件后运行,看下运行哪个程序。

建立工程

详细的Verilog文件如下:

golden工程

module Top_MultiBoot_Module_A (
    input CLK,
 output reg[3:0]LED_Out
);   
    
  
  

wire RESET;

assign RESET = 1'b1;


//
//首先定义一个时间计数寄存器counter,每当达到预定的100ms时,
//计数寄存器就清零,否则的话寄存器就加1??//然后计算计数器计数的最大值。时钟频率为12MHZ??//也就是周期为1/12M ??3ns,要计数的最大值为T100MS= 100ms/83ns-1 = 120_4818??//

reg[31:0] counter;
parameter T100MS = 25'd920_4818;

always @ (posedge CLK)

if(counter==T100MS)

 counter<=25'd0;

else

 counter<=counter+1'b1;

always @ (posedge CLK or negedge RESET)  
if(!RESET)  
 LED_Out<=4'b0001;        //初值,最低位led[0]灯亮  
 else if(counter==T100MS)  
 begin  
  if(LED_Out==4'b0000)      //当溢出最高位时  
   LED_Out<=4'b0001;    //回到复位时的状态  
  else  
   LED_Out<=LED_Out<<1;     //循环左移一位 
 end

endmodule // Run_LED

update工程

module Top_MultiBoot_Module_B (
    input CLK,
 output reg[3:0]LED_Out
);   
    
  
  


wire RESET;

assign RESET = 1'b1;



//
//首先定义一个时间计数寄存器counter,每当达到预定的100ms时,
//计数寄存器就清零,否则的话寄存器就加1��//然后计算计数器计数的最大值。时钟频率为12MHZ��//也就是周期为1/12M ��3ns,要计数的最大值为T100MS= 100ms/83ns-1 = 120_4818��//

reg[31:0] counter;
parameter T100MS = 25'd920_4818;

always @ (posedge CLK)

if(counter==T100MS)

 counter<=25'd0;

else

 counter<=counter+1'b1;

always @ (posedge CLK or negedge RESET)  
if(!RESET)  
 LED_Out<=4'b0001;        //初值,最低位led[0]灯亮  
 else if(counter==T100MS)  
 begin  
  if(LED_Out==4'b0000)      //当溢出最高位时  
   LED_Out<=4'b0001;    //回到复位时的状态  
  else  
   LED_Out<=LED_Out<<1;     //循环左移一位 
 end

endmodule // Run_LED

两个工程基本一样,流水的操作是在约束里实现的。

golden工程约束

#CLOCKS
#SYSCLK 
set_property IOSTANDARD LVCMOS18 [get_ports CLK]
set_property PACKAGE_PIN D27 [get_ports CLK]

#GPIO LEDs
# set_property PACKAGE_PIN AB8 [get_ports LED_REVXX[7]]
# set_property IOSTANDARD LVCMOS15 [get_ports LED_REVXX[7]]
# set_property PACKAGE_PIN AA8 [get_ports LED_REVXX[6]]
# set_property IOSTANDARD LVCMOS15 [get_ports LED_REVXX[6]]
# set_property PACKAGE_PIN AC9 [get_ports LED_REVXX[5]]
# set_property IOSTANDARD LVCMOS15 [get_ports LED_REVXX[5]]
# set_property PACKAGE_PIN AB9 [get_ports LED_REVXX[4]]
# set_property IOSTANDARD LVCMOS15 [get_ports LED_REVXX[4]]

# set_property PACKAGE_PIN AE26 [get_ports LED_Out[3]]
# set_property IOSTANDARD LVCMOS33 [get_ports LED_Out[3]]
set_property PACKAGE_PIN T21 [get_ports LED_Out[2]]
set_property IOSTANDARD LVCMOS33 [get_ports LED_Out[2]]
set_property PACKAGE_PIN T20 [get_ports LED_Out[1]]
set_property IOSTANDARD LVCMOS33 [get_ports LED_Out[1]]
set_property PACKAGE_PIN R24 [get_ports LED_Out[0]]
set_property IOSTANDARD LVCMOS33 [get_ports LED_Out[0]]

# CFGBVS and SPI mode properties

set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 2.5 [current_design]
set_property CONFIG_MODE SPIX1 [current_design]

#Compress the bitstream to fit on 128M QSPI of the K7
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]

#BITSTREAM PROPERTIES REQUIRED FOR GOLDEN IMAGE:
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 1 [current_design]
set_property BITSTREAM.CONFIG.CONFIGFALLBACK ENABLE [current_design]
set_property BITSTREAM.CONFIG.NEXT_CONFIG_ADDR 0x0400000 [current_design]

#(If the SPI flash is equal to or greater than 256 Mb, uncomment the constraint below):
#set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design]

这里解释一下,前面物理约束不重要,因为“穷”,我的板子只有3颗LED,所以只进行了三个物理约束。

CFGBVS and SPI mode properties及Compress the bitstream to fit on 128M QSPI of the K7、BITSTREAM PROPERTIES REQUIRED FOR GOLDEN IMAGE是重点约束的对象,具体解释看下表一。

set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 1 [current_design]
set_property BITSTREAM.CONFIG.CONFIGFALLBACK ENABLE [current_design]
set_property BITSTREAM.CONFIG.NEXT_CONFIG_ADDR 0x0400000 [current_design]

这三个约束是和UPDATE工程有关,一个是SPI的BUSWIDTH,一个是否开启CONFIGFALLBACK,最后一个是地址,这是非常重要的。

接下来是update工程的约束文件

#CLOCKS
#SYSCLK 
set_property IOSTANDARD LVCMOS18 [get_ports CLK]
set_property PACKAGE_PIN D27 [get_ports CLK]

#GPIO LEDs
# set_property PACKAGE_PIN AB8 [get_ports LED_REVXX[7]]
# set_property IOSTANDARD LVCMOS15 [get_ports LED_REVXX[7]]
# set_property PACKAGE_PIN AA8 [get_ports LED_REVXX[6]]
# set_property IOSTANDARD LVCMOS15 [get_ports LED_REVXX[6]]
# set_property PACKAGE_PIN AC9 [get_ports LED_REVXX[5]]
# set_property IOSTANDARD LVCMOS15 [get_ports LED_REVXX[5]]
# set_property PACKAGE_PIN AB9 [get_ports LED_REVXX[4]]
# set_property IOSTANDARD LVCMOS15 [get_ports LED_REVXX[4]]

# set_property PACKAGE_PIN AE26 [get_ports LED_Out[3]]
# set_property IOSTANDARD LVCMOS33 [get_ports LED_Out[3]]
set_property PACKAGE_PIN R24 [get_ports LED_Out[2]]
set_property IOSTANDARD LVCMOS33 [get_ports LED_Out[2]]
set_property PACKAGE_PIN T20 [get_ports LED_Out[1]]
set_property IOSTANDARD LVCMOS33 [get_ports LED_Out[1]]
set_property PACKAGE_PIN T21 [get_ports LED_Out[0]]
set_property IOSTANDARD LVCMOS33 [get_ports LED_Out[0]]

# CFGBVS and SPI mode properties

set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 2.5 [current_design]
set_property CONFIG_MODE SPIX1 [current_design]

#Compress the bitstream 
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]

#BITSTREAM PROPERTIES REQUIRED FOR GOLDEN IMAGE:
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 1 [current_design]
set_property BITSTREAM.CONFIG.CONFIGFALLBACK ENABLE [current_design]

#(If the SPI flash is equal to or greater than 256 Mb, uncomment the constraint below):
#set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design]

物理约束同样不重要,重要的还是下面的和multiboot相关的约束,具体解释和上面一样。

生成Bit流并运行

上述两个工程分别生成Bit流并运行,查看两个流水灯是否是两个不同方向的。

合成MCS文件并运行

将两个BIT流文件合成一个MCS文件,命令如下:

write_cfgmem -format mcs -interface SPIX1 -size 16 -loadbit "up 0 <path>/golden.bit up
0x0400000 <path>/update.bit" <path>/filename.mcs

两个bit流文件位置;

filename: mcs文件名称。

将上诉mcs文件下载到FPGA开发板上,可以看见update工程文件运行。

破坏Golden文件

回退到Golden可以通过不同的方式触发。主要有以下几种方式:

  1. ID Code错误

  2. CRC错误

  3. Watchdog超时

  4. BPI地址越界

有关更多信息,请参阅UG470中的重新配置和多引导章节。

本应用说明演示了由CRC错误触发的回退。可以手动损坏更新位流以导致CRC错误。在RESET CRC命令和CRC命令之间有许多可以翻转位的位置。下图显示了一个示例。

  • 1.使用十六进制编辑器(HxD Hex Editor)中打开更新(update)比特流(.bit),在比特流中间翻转一些数据字节,例如从00到11,如图所示。

为了保证破坏彻底,可以多更改几处。

  1. 保存损坏的更新位流,并使用此损坏的位流生成新的闪存编程文件(.mcs)。

write_cfgmem -format mcs -interface SPIX1 -size 16 -loadbit "up 0 <path>/golden.bit up
0x0400000 <path>/update.bit" <path>/filename.mcs
  • 3.重新下载文件

观察是Golden还是update文件运行,同理可以将上诉命令修改,将golden和update更换一下mcs文件位置,对比测试,上诉两个情况本人都有亲自测试过,都是golden文件运行,证明multiboot已经生效。

工程下载

其中,第一个《xapp1247-multiboot-spi.pdf》是官方关于Multiboot的使用参考,最后面还有Watchdog超时实例演示。

《xapp1247-multiboot-spi.zip》是《xapp1247-multiboot-spi.pdf》里的参考实例,使用VHDL设计,也是我在《【Vivado那些事】如何查找官网例程及如何使用官网例程》里说的查找官方历程的方式获取。

《Multiboot_OpenFPGA.zip》是我本次演示的实例,里面有十六进制文件查看器及相关的命令。

链接地址:

链接:https://pan.baidu.com/s/1vi7Q1Jkh5FXoW4zFi0LoMA
提取码:open

大家知道,我分享的BD网盘经常会链接失效(和客服杠了几百回也没用),中国移动和彩云客服说是他们网盘链接不会失效,并且下载不会限速,所以后面会慢慢切换过去,和彩云的链接(本人还在试用中):

链接:https://caiyun.139.com/m/i?1B5CvFWH20yx9
提取码:buC7

NOW

Xilinx 7系列FPGA Multiboot介绍-远程更新


【Vivado那些事】Vivado两种生成、固化烧录文件


【Vivado那些事】如何查找官网例程及如何使用官网例程


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Pieces_thinking/article/details/120192503

智能推荐

c语言用递归方法实现冒泡排序,C语言 冒泡排序 递归法_weixin_39715834的博客-程序员秘密

1 #include 2 #include 3 int main()4 {56 void bubble(int *a,int n);78 int i,n,a[100];910 printf("请输入数组中元素数量(不大于100个):");11 scanf("%d",&amp;n);1213 for(;n&lt;1||n&gt;100;){14 ...

Go 交叉编译x86, arm架构上的Linux可执行程序_叨陪鲤的博客-程序员秘密

1. Golang的交叉编译说明????????????golang中交叉编译非常简单。????????????直接在windows上设置几个Go环境变量便可以编译多种架构多个操作系统的可执行程序。https&gt;go envset GO111MODULE=autoset GOARCH=amd64set GOBIN=set GOCACHE=C:\Users\Admin\AppData\Local\go-buildset GOENV=C:\Users\Admin\AppData\Roamin

雪花ID(Go 实现)_wang豪的博客-程序员秘密_golang 雪花id

雪花ID的实现之前做项目的时候遇到,今天再深入理解一下。文章目录雪花ID的实现前言一、雪花ID的作用?二、雪花ID的原理三、雪花ID的代码实现(Go 语言)四、雪花ID 的缺点前言雪花ID 最由推特开源的一种全局唯一ID 的生成算法,有递增、全局唯一等特性。一、雪花ID的作用?全局的唯一性对于多台机器,毫秒级生成多条不重复ID递增性生成的雪花ID具有递增型,可以加速查询。可用性高支持多线程,分布式的系统架构二、雪花ID的原理最高位是符号位,生成的ID总是正数,

OKHttp以文件形式上传图片_jianning-wu的博客-程序员秘密

AndroidOkhttp框架以文件形式上传图片以Post为例public Observable&amp;lt;String&amp;gt; postImageview(final String url, final MultipartBody requestBody){ //创建被观察者 Observable&amp;lt;String&amp;gt; observable...

LCD1602自定义符号的使用_Aprilis askua的博客-程序员秘密_lcd1602自定义字符

LCD1602自定义符号的使用在对LCD1602有了基本的了解与使用后,我们可以接着了解LCD1602的自定义字符的使用。要显示自定义符号,就得使用CGRAM存储器,LCD1602最多只可以显示8个自定义字符。CGRAM可以存储8个自定义字符,他们在存储器中的首地址分别为:0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78.把字模数据写入CGRAM,就需要从首地址中选一个,并将字模数据送入,切记要把CGRAM中的自定义字符再送入DDRAM,这样自定义字符才能够正常显示。

有5个学生,每个学生的数据包括学号、姓名、英语、数学、物理三门课的成绩,从键盘输入5个学生数据,要求输出每个学生3门课程的平均成绩,以及最高分的学生的信息。_拽拽惹人爱的博客-程序员秘密

**C++有5个学生,每个学生的数据包括学号、姓名、英语、数学、物理三门课的成绩,从键盘输入5个学生数据,要求输出每个学生3门课程的平均成绩,以及最高分的学生的信息(包括学号、姓名、3门课的成绩、平均成绩)。**在这里插入代码片#include&lt;iostream&gt;using namespace std;struct Student { int num; ...

随便推点

HTTPS 协议核心原理_爱好学习的青年人的博客-程序员秘密

HTTPS 协议核心原理“安全”的四个特性机密性(加解密)完整性(摘要算法)身份认证(接收方确认身份)不可抵赖(发送方不能否认自己的行为)后两个通过私钥加密,公钥解密 以及 摘要算法实现的数字签名 进行实现对称加密对称加密: 客户端和服务器共享同一个密钥,客户端给服务器发消息时,客户端用此密钥加密,服务器用此密钥解密;反过来,服务器给客户端发消息时,相反的过程。这种加密方式在互联网上有两个问题:**1. 密钥如何传输?**密钥A的传输也需要另外一个密钥B,密钥B的传

分布式数据库一定会替代Oracle吗?_dotNET跨平台的博客-程序员秘密

在传统数据库领域,Oracle一直占据了很大的市场份额,很多企业的业务系统基于此实现OLTP交易场景。近年来,随着分布式技术的发展,分布式数据库逐渐占据了OLTP领域较大的市场,尤其在互联...

使用JSON Server在项目中配置Mock数据以及json server的基本数据操作_无处不楼台的博客-程序员秘密

1、项目根目录下键入:yarn add json-server -D等待安装成功。2、在项目根目录下新建文件夹“__json_server_mock__”.这个文件夹名字前后代两个杠,代表这个文件夹实际与本项目代码关系不大。3、在此新建文件夹中创建文件“db.json”,写入:{ "user":[]}4、再在package.json中找到以下代码,并添加代码:"scripts": { "start": "react-scripts start",

r语言 与python r中python环境的创建_youngleeyoung的博客-程序员秘密

#remotes::install_github(“rstudio/reticulate”)library(reticulate)use_condaenv(‘C:/Users/yll/AppData/Local/r-miniconda/envs/giotto_env/’)‘’’conda_install(envname = “giotto_env” , packages=c(“pandas”, “python-igraph”, “networkx”, “python-louvain”, “leid

数组_学无止境0101的博客-程序员秘密

数组数组的定义数组是相同类型数据的有序集合数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成的其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问他们数组声明创建首先必须声明数组变量,才能在程序中使用数组。下面是声明数组变量的语法:dataType[] arrayRefVar; //首选的方法或dataType arrayReFVar;//效果相同但不是首选方法Java语言使用new操作符来创建数组,语法如下:dataType[] arra

在Linux下编写运行你的第一条代码——Hello Linux_Q-WHai的博客-程序员秘密

最近刚接触Linux,也是在啃那个公认的《鸟哥的Linux私房菜》。是的,的确讲得挺好的。现在看到第10章 vim程序编辑器。虽然鸟哥不太建议我们跳着来阅读他的文章,但是我还是跳了一两个章节没有阅读。别误会,我不是大牛。其实,知道vim也不是学到这一章才了解的。之前是知道的,也用过。不过想在vim中编写C代码的还就是刚刚的想法。于是,我做了一个实验。

推荐文章

热门文章

相关标签