MicroBlaze在纯FPGA下 Xilinx SDK固化程序到外部SPI FLASH

外部SPI FLASH: Micron N25Q128A13ESE40G (128Mbit (16MByte))
FPGA: XC7A100T 
CPU: Microblaze

第一种情况: Microblaze在简单的应用,比如运行LED,IIC,SPI,UART之类的低俗接口驱动,或做一些简单的辅助型工作时,一般生成的application elf文件都不大,在10几KB或者几十,百几KB,此时使用FPGA内部的BRAM资源已经足够。 XC7A100T本身就有600几KB的BRAM资源。这种情况下直接将 硬件流文件 和 elf 文件 合并为download.bit文件,在直接烧录到外部SPI FLAH即可。

1. Xilinx -- Program FPGA (合并硬件流和app.elf, 生成download.bit)

当Program完成后,FPGA已经可以运行起来了,不过这不是固化,断电重启后就消失。

2. Xilinx -- Program Flash

 Program完成后,断电重启即可。简单!!!

 因为我们使用的SPI flash支持x4, 在xdc加入下面代码大大加快加载速度:
 

set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]
set_property BITSTREAM.GENERAL.COMPRESS true [current_design]
set_property BITSTREAM.CONFIG.CONFIGRATE 50  [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
set_property CONFIG_MODE SPIx4 [current_design]

第二种情况: 当Microblaze需要运行文件系统,网络协议栈,例如lwip时,编译代码最终可能会高达几十MB,此时就需要通过SREC SPI Bootloader从SPI Flash加载elf到外部DDR运行。

1. 因为需要从SPI Flash读取应用文件,Vivado BD硬件需要添加 AXI Quad SPI IP, 配置如下:

 

引出引脚,命名为qspi_flash, xdc下加入引脚定义:

#spi_flash
set_property IOSTANDARD LVCMOS33 [get_ports {qspi_flash_ss_io[0]}] 
set_property IOSTANDARD LVCMOS33 [get_ports qspi_flash_io0_io] 
set_property IOSTANDARD LVCMOS33 [get_ports qspi_flash_io1_io] 
set_property IOSTANDARD LVCMOS33 [get_ports qspi_flash_io2_io] 
set_property IOSTANDARD LVCMOS33 [get_ports qspi_flash_io3_io]

set_property PACKAGE_PIN T19 [get_ports {qspi_flash_ss_io[0]}]
set_property PACKAGE_PIN P22 [get_ports qspi_flash_io0_io] 
set_property PACKAGE_PIN R22 [get_ports qspi_flash_io1_io] 
set_property PACKAGE_PIN P21 [get_ports qspi_flash_io2_io] 
set_property PACKAGE_PIN R21 [get_ports qspi_flash_io3_io]

#qspi_flash_ss_io[0] 为 QSPI_CS
#qspi_flash_io0_io   为 QSPI_DQ0
#qspi_flash_io1_io   为 QSPI_DQ1
#qspi_flash_io2_io   为 QSPI_DQ2
#qspi_flash_io3_io   为 QSPI_DQ3
#QSPI_CLK 不用接

 保存,生成硬件流文件 top_wrapper.bit

2. 进入SDK, 新建工程。 File --  New-- Application Project

Next >
 

 Finish

可以看到Project Explorer下建立刚刚的新工程

 3.设置 FLASH_IMAGE_BASEADDR的offset (这个offset是在SPI Flash 存储应用程序的Flash偏移量)

外部Flash大小为16MByte, 我们设置前面大概8MB存放top_wrapper.bit 和 SREC BootLoader.elf, 后面存放app. 需要根据实际FPGA容量进行调整。

修改blconfig.h 

4.因为SREC BootLoader是加载到BRAM运行的,所以确保其在BRAM

5. 右键lwipbootloader_bsp -- Board Support Package Setting. 修改xilisf, 设置serial_flash_family=5, 因为我们使用Micron,其他不变

6. 编译,生成的lwipbootloader.elf 大小18.208KB

7. 先合并硬件流文件和lwipbootloader.elf,生成download.bit

 8. 烧写download.bit 到Flash中,记住这里的Offset = 0

 9. 再烧写应用程序即之前的lwiptcp.elf (这个文件的代码大小为507KB,可以烧录到Flash,但其加上未定义变量,需要30几MB空间,所以需要加载到DDR中运行)

 注意: Image File选择lwiptcp.elf应用程序文件,Offset为之前设置的0x80000, 同时需要勾选Convert ELF to bootloadable SREC format and program,因为应用程序是通过转换为SREC格式保存在Flash中。使用SREC格式也导致了代码固化后加载时间极其漫长,如何优化关注我另外一篇文章。

10. 断电重启,OK?  ??

 为什么只打印了SREC SPI BootLoader就没有反应?

查看bootloader.c main函数, 

 简单修改一下,保证这个初始化函数有足够的时候等待Flash就OK了

	volatile int wait;

	do
	{
	    Status = XIsf_Initialize(&Isf, &Spi, ISF_SPI_SELECT, IsfWriteBuffer);
	    if (Status != XST_SUCCESS)
	    {
	        xil_printf("XIsf_Initialize failed! Status=%d\r\n", Status);

			for (wait=0; wait < 100000; wait++);
			for (wait=0; wait < 100000; wait++);
	    }
	} while (Status != XST_SUCCESS);

用一个循环,直到初始化成功。编译,合并生成download.bit, 重新program即可。(这个时候应用程序不用再下载,因为之前已经下载过了)

 SREC Bootloader 不断一条一条读取应用程序并加载。

  • 7
    点赞
  • 79
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值