一:参考资料
1.选定镁光的falsh
Debug一下bootloader工程,串口只输出了一个SREC SPI Bootloader。单步调试发现,是XIsf_Initialize出错了,返回了1,程序直接退出了main函数。再继续分析,发现程序走的是Atmel的分支,没有走Micron的分支,打开xparameters.h一看,XPAR_XISF_FLASH_FAMILY的值为1,说明设置的serial_flash_family根本就没有生效!
2.
第二个地方就是,要点开Generate linker script看一下,bootloader是不是已配置为在BRAM里面运行,主程序是否是在DDR内存里面运行。如果不是,就要手动改过来。————————这里可以推测出来bootloader难道只能引导APP程序运行在BRAM里面 (因为SREC BootLoader是加载到BRAM运行的,所以确保其在BRAM)该段话就证明了——之前的猜想:SREC BootLoader函数只能将app程序(app程序可以放在DDR3里,也可以放在falsh里面可以用mig和qspi写进和读出到BRAM运行)引导如BRAM运行。
同理的
再烧写应用程序即之前的lwiptcp.elf (这个文件的代码大小为507KB,可以烧录到Flash,但其加上未定义变量,需要30几MB空间,所以需要加载到DDR中运行)注意: Image File选择lwiptcp.elf应用程序文件,Offset为之前设置的0x80000, 同时需要勾选Convert ELF to bootloadable SREC format and program,因为应用程序是通过转换为SREC格式保存在Flash中。使用SREC格式也导致了代码固化后加载时间极其漫长,如何优化关注我另外一篇文章。
3.第三个地方找了很久才发现,Program FPGA对话框里面默认的BRAM内容选的是bootloop,和那篇文章的差别就在这里!这里应该选择bootloader.elf才对!选择好了之后,点Program按钮合并Vivado的bit文件,以及Vitis bootloader工程的elf文件,生成download.bit。
4.下载download.bit文件到SPI Flash的0地址处:
5.下载主程序的elf文件到SPI Flash的非零地址处,注意勾选Convert ELF to SREC的复选框:
6.Microblaze不需要外部DDR3内存也能独立运行,用BRAM作运行内存,这样一来,Vitis编译出来的elf文件可以在Program FPGA对话框里面直接和Vivado的bit文件整合,生成download.bit,然后在Program Flash Memory中把download.bit文件烧到SPI Flash的0地址处,就可以上电开机运行了。不需要SREC SPI Bootloader。在这种情况下,程序代码和程序变量都是保存在BRAM里面的。
7. 当Microblaze需要运行文件系统,网络协议栈,例如lwip时,编译代码最终可能会高达几十MB,此时就需要通过SREC SPI Bootloader从SPI Flash加载elf到外部DDR运行
因为需要从SPI Flash读取应用文件,Vivado BD硬件需要添加 AXI Quad SPI IP, 配置如下:
8.
设置 FLASH_IMAGE_BASEADDR的offset (这个offset是在SPI Flash 存储应用程序的Flash偏移量)
外部Flash大小为16MByte, 我们设置前面大概8MB存放top_wrapper.bit 和 SREC BootLoader.elf, 后面存放app. 需要根据实际FPGA容量进行调整
二:总结
1.SREC SPI BOOtloader 只能将应用程序从flah拿到BRAM运行(不能拿到SDRAM运行)
2.bit文件还是需要icap原语来从falsh拿bit到SDRAM运行
3.应用程序大就可以在DDR3里面运行
4.程序小就可直接在BRAM 里面运行(速度还较DDR3快一些)