microblaze
Xilinx microblaze一般用来在系统中做一些控制类和简单接口的辅助性工作,比如运行IIC、SPI、UART之类的低速接口驱动,对FPGA逻辑功能模块初始化配置及做些辅助计算等等。当程序代买量不大(在十几KB到几时KB之间),程序运行时直接使用FPGA内部RAM资源已经够用。但是,当Microblaze需要运行文件系统、USBHCD、网络协议栈甚至是操作系统时,代码量可能会高达几MB甚至是几十MB的规模,此时程序就必须在外部存储器运行了,这就需要一个小的初始化程序,将程序搬移到外设中,然后启动主程序,这个程序就是bootloader
关系介绍
工程bitstream,bootloader引导程序,microblaze应用主程序三者之间的关系如下图:
上电后FPGA先加载bitStream,然后是bootloader程序,然后软核运行bootloader程序将应用主程序从flash中搬移到DDR里面,最后从DDR里面启动我们的应用主程序。
工程介绍
工程中,led2的闪烁通过verilog来控制,生成bit文件;led3的闪烁在microblaze中控制,作为microblaze中的主程序,生成.elf文件
硬件搭建
添加axi_quad_spi IP时需注意:
(1)mode选择Quad(硬件上为qspi配置flash),如果配置flash的引脚接到FPGA的专用spi引脚上,则需要勾选"Enable STARTUP Primitive",否则不勾选;
(2)ext_spi_clk:在QSPI模式下这个时钟的两分频就是给SPI Flash的访问时钟,因此这个时钟要根据QSPI Flash的参数设置到合理值;
microblaze程序
创建microblaze主程序
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xgpio.h"
#include "sleep.h"
XGpio LED3;
int main()
{
init_platform();
print("Hello World\n\r");
XGpio_Initialize(&LED3, XPAR_LED3_DEVICE_ID);
while(1)
{
XGpio_DiscreteWrite(&LED3, 1, 0x00000001);
usleep(1000000);
XGpio_DiscreteWrite(&LED3, 1, 0x00000000);
usleep(1000000);
}
cleanup_platform();
return 0;
}
通过修改Generate Linker Script使主程序在ddr3中运行
创建bootloader程序
新建Application project,选择SREC SPI Bootloader(只有bd中例化了axi quad spi IP才可创建该程序)
修改xilisf库,serial_flash_family=5选择Micron 系列QSPI Flash(根据板子上flash型号选择) ;如果采用其他公司的flash,请查看serial_flash_family后的Description,有对应关系;serial_flash_interface=1选择AXI 接口
修改microblaze所要下载到flash的偏移地址 :bootloader -> blconfig.h(该地址根据实际情况指定)
注意:bootloader.elf的Generate Linker Script需要为local memory,因为该bootloader.elf为加载引导程序,需要在fpga内运行
烧录文件
Program Fpga
该部分的目的是将fpga bit与bootloader.elf组合为download.bit文件
Program Flash
第一步:烧录download.bit文件,注意offset的设置
第二步:烧录SREC文件(.elf转化) ,注意offset设置,与blconfig.h中的地址对应;convert ELF to……需要勾选
烧录过程中存在的问题:
(1)program flash过程中速度太慢;
(2)烧录结束上电进行程序运行时,程序启动速度太慢
大佬解决方案:https://blog.csdn.net/natty715/article/details/104241415