上一节我们只使用ZYNQ的PL端资源,单独控制PL端的LED实现流水灯:。但是掉电后程序会丢失,那么如何固化代码到FLASH呢?就是本节的目的了。

一、ZYNQ的启动流程

        ZYNQ7000 SOC 芯片可以从 FLASH 启动,也可以从 SD 卡里启动, 本节介绍程序 FLASH 启动的方法。Zynq7000 SOC 芯片上电后,最先运行的是ARM端系统(PS)。然后再通过ARM系统软件部分加载FPGA的比特流文件.bit至FPGA(PL),配置FPGA PL端的逻辑功能。

如果是linux开发:

        则只需固化uboot到boot.bin。这样系统启动后,除了配置FPGA端资源,ARM端则运行uboot,uboot负责加载内核到指定位置并启动内核开始运行。

1.1 ZYNQ启动分为两个阶段

  • 第一阶段是 BOOT ROM(ZYNQ厂家固化代码)
  • 第二阶段是 FSBL (First Stage Bootloader)SDK工具来制作。

经过以上两个阶段,PL端配置程序及arm端程序才开始运行。

1.1 第一阶段 (BOOT ROM)

  • 上电后,Zynq7000 SOC 会首先执行片内 Boot ROM 代码,Boot ROM 代码读取 Boot mode 寄存器来判断是哪一种启动方式(SD card/QSPI Flash/JTAG)。
  • 确定好哪种启劢方式后,Boot ROM 从相应的启动设备(SD Card/QSPI Flash)加载 First Stage Bootloader (FSBL) 到On Chip Memory(OCM) RAM,并且将执行权交付给 FSBL。

1.2 第二阶段 FSBL (First Stage Bootloader)

使用SDK 工具一步步生成 FSBL 代码和可执行文件,结合代码可知 FSBL 主要做了如下工作:

  • 初始化 CPU,初始化串口;
  • Processor System (PS) 一些控制器的初始化,如 MIO, PLL, CLK and DDR;
  • 禁止 L1 Data Cache;
  • 注册 ARM 中断向量;
  • 通过 Boot mode 寄存器,判断是哪种启动方式。

1.2.1 QSPI Flash 启动方式:

  • 初始化 QSPI Flash 控刢器;
  • 从 Flash 拷贝 system.bit 到 FPGA (如果 Flash 中存有 system.bit);
  • 从 QSPI Flash 拷贝应用程序的代码到DDR3;
  • 调转到应用程序执行;

1.2.2 SD Card 启动方式:

  1. 初始化 SD 控刢器;
  2. 从 SD Card 拷贝 system.bit 到 FPGA (如果 BOOT.BIN 中存有 system.bit);
  3. 从 SD card 拷贝应用程序的代码到 DDR3;
  4. 跳转到应用程序执行;

1.2.3 JTAG 启动方式,直接退出。

2 制作BOOT.bin

2.1 新建项目

参考LED实验时创建工程的方式:

2.2 配置PS端资源、启动SDK、生成BOOT.bin

(1)ZYNQ 的PS开发一般有原理框图的形式来设计,这样硬件的连接看起来会更加直观。点击 Create Block Design 按钮来添加原理图设计文件。

zynq 无SD卡 启动 emmc_初始化

在弹出的对话框里输入原理图设计文件的名字,返里我们取名为"system"。

zynq 无SD卡 启动 emmc_初始化_02

(2)出现 Diagram 的空白对话框,点击 图标+添加 ARM 处理器内核到这个空白的原理图里。

zynq 无SD卡 启动 emmc_zynq 无SD卡 启动 emmc_03

返里有很多 Xilinx 提供的 IP,我们找到 ZYNQ7 Processing System 双击添加,不要选择后面带 BFM(总线功能模型),带 BFM 的 IP 为早期IP 处理器版本。

zynq 无SD卡 启动 emmc_初始化_04

zynq 无SD卡 启动 emmc_应用程序_05

(3)双击 Diagram 界面里的 ZYNQ Processing System,打开 ZYNQ 系统的配置界面。

zynq 无SD卡 启动 emmc_初始化_06

其中 Page Navigator 界面下有 8 个子项,分别为 Zynq Block Design, PS-PL Configuration,Peripheral I/O Pins, MIO Configration, Clock Configuration, DDR Configuration, SMC Timing Calculation, Interrupts。这些页面选项是针对 ZYNQ 的不同硬件模块的配置,其中

PS_PL 页面提供了 PS 到 PL 的相关接口配置信息以及 PS 部分一些配置信息;

Peripheral I/O Pins 页面主要是对一些通用外设接口的配置;

MIO Configruation 页面主要是对 MIO 已经EMIO 的分配控制;

Clock Configruation 页面主要是对 PS 端时钟资源的配置和管理;

DDR Configration 页面主要是对 DDR控制器一些参数的配置;

Interrupts 页面主要是对中断进行配置管理。

(4)点击 Peripheral I/O Pins ,会出现以下的 IO 配置界面。

因为 ZYNQ 的MIO 管脚可以配置成多种功能,比如 MIO48 和 MIO49, 既可以配置成 SD1引脚,也可以是 UART1 引脚,或者是 I2C1 引脚,也可以配置成 CAN1 引脚。具体如何配置需要跟硬件电路板的原理图对应。我们 MIO48 和 MIO49 是连接到 UART 芯片上,是作为串口通信使用。使能SD、 Quad SPI Flash。

zynq 无SD卡 启动 emmc_zynq 无SD卡 启动 emmc_07

zynq 无SD卡 启动 emmc_应用程序_08

zynq 无SD卡 启动 emmc_初始化_09

(5)点击 PS-PL Configuration ,在 Gemeral 目录下,我们可以看到UART1 波特率是115200,这个波特率用户可以自己选择,我们返里就保留默认设置就可以了。

zynq 无SD卡 启动 emmc_zynq 无SD卡 启动 emmc_10

(6)点击 Clock Configuration ,返个界面会显示 ZYNQ 系统的一些时钟,比如输入时钟是33.33333Mhz, 这个时钟跟我们开发板上的 PS 的系统时钟是一样的。另外我们可以看到 CPU工作时钟是 666.666666Mhz(767Mhz), DDR 的工作时钟是533.333333Mhz,还有些是外设的工作时钟。这些时钟频率我们目前不需要修改。

zynq 无SD卡 启动 emmc_应用程序_11

(7) 再打开 DDR Configration,在这个界面上是选择 DDR 芯片的名称和一些参数。我们再 Memory Part 中需要选择跟开发板上 DDR3 型号一样的名称(MT41J256M16 RE-125)。

zynq 无SD卡 启动 emmc_初始化_12

(8) 在 MIO Configuration 顷,把 Quad SPI Flash 的 MIO1~MIO6 Speed 配置成 fast 模式。

zynq 无SD卡 启动 emmc_开发板_13

在 SD_0 项,选择 CD 前面的钩,IO 选择 MIO47(需要跟开发板一致),SD_0 的 IO 速度配置成 fast 模式。再配置 Bank1 I/O Voltage 的电压为 1.8V。

zynq 无SD卡 启动 emmc_开发板_14

(9)在 Clock Configuration中,我们可以修改 QSPI 癿时钟频率,默认是 200Mhz。这里不做修改。

zynq 无SD卡 启动 emmc_应用程序_15

(10)在 Diagram 界面里点击"Run Block Automation"完成对 ZYNQ7 Processing System IP核的配置,生成外部 ZYNQ 系统的外部链接 IO 管脚。

zynq 无SD卡 启动 emmc_应用程序_16

zynq 无SD卡 启动 emmc_开发板_17

生成后的 ZYNQ 系统外部管脚如下,一个是 DDR 的接口,一个是 FIXED_IO。

zynq 无SD卡 启动 emmc_zynq 无SD卡 启动 emmc_18

(11)在 Source 窗口中选中 system.bd,右键并先后选择Generate Output Projects 和 Create HDL Wrapper 选顷迕行操作。生成后如下图所示:

zynq 无SD卡 启动 emmc_初始化_19

(12)在system_wrapper.v中例化LED程序,并添加相应的管教约束文件。具体可参考PL端的流水灯实验。

(13)重新编译一下工程,生成 bit 文件。

(14)再导出硬件,选择菜单 File->Export->Export Hardware...导出,包含bitstram 文件。

(15)硬件导出后,选择菜单 File->Launch SDK,启动 SDK 开发环境, 会出现1 个 hardware platform:sytem_wrapper_hw_platform_0。

zynq 无SD卡 启动 emmc_开发板_20

(16)进入SDK 开发环境后,点击菜单 File -> New -> Application Project。

zynq 无SD卡 启动 emmc_zynq 无SD卡 启动 emmc_21

(17)仅在 Project name: 输入 fsbl,Hardware Platform 需要选择system_wrapper_hw_platform_0。

zynq 无SD卡 启动 emmc_应用程序_22

next,选择 Zynq FSBL 模板

zynq 无SD卡 启动 emmc_zynq 无SD卡 启动 emmc_23

(18)软件会自动编译生成 fsbl.elf 文件。

(19)为了能够让串口打印出 Bootloader 癿信息,我们返里需要在 fsbl_debug.h 文件里添加一条语句,定义一下“FSBL_DEBUG_INFO”常量。修改后保存,重新编译一下 fsbl 项目。

zynq 无SD卡 启动 emmc_zynq 无SD卡 启动 emmc_24

(20)接下去我们要把 FSBL 可执行文件,FPGA PL的bit比特流文件和PS应用程序结合成一个 Bin 文件。

选择菜单 Xilinx Tools->Create Boot Image:

zynq 无SD卡 启动 emmc_zynq 无SD卡 启动 emmc_25

点击 Browse 选择选择 Zynq Boot Image 文件.bif 的存放地址。

zynq 无SD卡 启动 emmc_开发板_26

(21)点击 Add按钮, 在弹出的Add new boot image partition 对话框中, 点击 Browse 选择我们刚生成的 FSBL 可执行文件 fsbl.elf。返里 Partition type 为 bootloader,fsbl.elf 作为bootloader 程序。

zynq 无SD卡 启动 emmc_初始化_27

(22)点击 Add 按钮,在弹出的 Add new boot image partition 对话框中, 点击 Browse 按钮找到 FPGA PL的比特流文件 system_wrapper.bit, 这里 Partition type 为 datafile。

zynq 无SD卡 启动 emmc_应用程序_28

(23)同样的方法添加应用程序文件如uboot。 返里 Partition type 也是 datafile。3 个文件添加后如下所示:

zynq 无SD卡 启动 emmc_zynq 无SD卡 启动 emmc_29

(24)点击 Create Image 按钮,生成 BOOT.bin。BOOT.bin 文件生成成功。

zynq 无SD卡 启动 emmc_zynq 无SD卡 启动 emmc_30

3、烧写 FLASH 并启动

把生成癿 BOOT.bin 文件烧写到 QSPI FLASH 中

(1)开发板需要连接 JTAG 线到电脑,把开发板的上电启动配置跳线帽选择至 QSPI Flash 启劢,并上电。

(2)在 SDK开发环境里,选择菜单 Xilinx Tools->Program Flash。

zynq 无SD卡 启动 emmc_zynq 无SD卡 启动 emmc_31

(3)在 Program Flash Memory 里, Hardware Platform 中选择 system_wrapper_hw_platform_0, 烧写癿 Image File 选择刚生成的 BOOT.bin 文件,Flash Type 选择 qspi_single。

zynq 无SD卡 启动 emmc_zynq 无SD卡 启动 emmc_32

(4)点击 Program 按钮下载,程序会开始下载 BOOT.bin 文件到开发板的 QSPI FLASH 中。

zynq 无SD卡 启动 emmc_初始化_33

Console 窗口显示 Flash Operation Successful 信息,说明烧写成功。

zynq 无SD卡 启动 emmc_开发板_34

(5)断电重新上电,如果开发板连接串口,我们可以在串口工具里看到 bootloader 的启动信息。

zynq 无SD卡 启动 emmc_初始化_35