zl程序教程

您现在的位置是:首页 >  硬件

当前栏目

【正点原子FPGA连载】第一章Hello World实验 摘自【正点原子】DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南

嵌入式开发 指南 实验 FPGA 原子 连载 Hello
2023-09-11 14:20:38 时间

1)实验平台:正点原子MPSoC开发板
2)平台购买地址:https://detail.tmall.com/item.htm?id=692450874670
3)全套实验源码+手册+视频下载地址: http://www.openedv.com/thread-340252-1-1.html

第一章Hello World实验

“Hello World!”是各种编程语言中最简单,同时也是最经典的入门实验。因此,我们将串口打印“Hello World”作为MPSOC嵌入式系统的开篇实验,这也是我们步入MPSOC的PS部分的始发点。通过本次实验我们将了解MPSOC嵌入式系统的开发流程,熟悉MPSOC嵌入式最小系统的搭建。
本章包括以下几个部分:
1.1简介
1.2实验任务
1.3硬件设计
1.4软件设计
1.5下载验证

1.1简介

首先我们来了解一下MPSOC嵌入式系统的开发流程。
在这里插入图片描述

图 1.1.1 MPSOC嵌入式系统开发流程
如上图所示,开发流程大体可以分为6步。其中step1至step4为硬件设计部分,在Vivado软件中实现;step5为软件设计部分,在Vitis软件中实现;step6为功能的验证。复杂的程序还涉及Debug,这个也是在Vitis软件中实施。具体每一步的操作我们会在后面详细介绍。
在简单了解嵌入式系统的开发流程后,接下来我们来看一下什么是嵌入式最小系统。嵌入式最小系统的概念包括以下两个方面:一、它是使系统正常工作的最小条件;二、它是其他系统建立的基础。
在这里插入图片描述

图 1.1.2 MPSOC嵌入式最小系统
如图 1.1.2所示,以ARM Cortex为核心、DDR为内存,加上传输信息使用的UART串口就构成了MPSOC嵌入式最小系统。可以看到,这个最小系统只包括了MPSOC中的PS部分。
下面我们将按照MPSOC嵌入式系统开发流程,一步步的搭建上图所示的最小系统。

1.2实验任务

本章的实验任务是在MPSOC开发板上搭建MPSOC嵌入式最小系统,并使用串口打印“Hello World”信息。

1.3硬件设计

在图 1.1.1中,我们将step1至step4划分为硬件设计部分。
step1:创建Vivado工程
1-1 打开Vivado,进入Vivado界面后,点击“Quick Start”栏的 “Create Project”。然后在弹出的创建Vivado工程向导界面,点击“Next”。如下图所示:
在这里插入图片描述

图 1.3.1 点击创建工程
在这里插入图片描述

图 1.3.2 创建工程向导
1-2 进入工程命名界面。设置工程名为“hello_world”,工程路径可使用任意路径,本章我们将该工程放在F:\ZYNQ\Embedded_System文件夹下。注意,工程名和路径只能由英文字母、数字和下划线组成,不能包含中文、空格以及特殊字符!
确认已经勾选“Create project subdirectory”,点击“Next”,如下图所示:
在这里插入图片描述

图 1.3.3 设置工程信息
在这里插入图片描述

图 1.3.4 选择工程类型
1-3 进入图 1.3.4所示的界面,在此界面设置工程类型。此处我们选择 “RTL Project”。本次实验不需要添加源文件和约束文件,所以勾选“Do not specify sources at this time”。勾选之后会省略后面添加源文件和约束文件的步骤,点击“Next”直接跳到器件选型界面。
1-4 器件选型界面。所选择的器件型号一定要跟开发板上的MPSOC芯片型号保持一致。开发板上的MPSOC芯片有两种型号,XCZU2EG和XCZU4EV。大家可以通过查看开发板上MPSOC芯片的丝印来确认所使用的芯片型号。其中XCZU2EG的speed等级为“-2”,XCZU4EV的speed等级为“-1”,这在器件选型的时候需要注意。此处以XCZU4EV为例。
选择器件型号的方式有两种,一种是根据Parts,另一种是根据Boards,此处我们使用Parts选择器件。在Family栏里选择“ZYNQ Ultrascale+MPSOCs”, Speed栏选择“-1”,需要注意的是,在Package栏选择“sfvc784”。然后根据开发板上的MPSOC芯片型号,在下面的器件列表中选择“xczu4ev-sfvc784-1-i”,如下图所示。若是XCZU2EG,相对应的器件为“xczu2eg-sfvc784-2-i”。
在这里插入图片描述

图 1.3.5 器件选型界面
选中之后,点击“Next”。
1-5 工程摘要界面。这是创建工程的最后一步,显示工程摘要信息,如图 1.3.6所示。在此界面检查前面所设置的工程名称、所选择的器件型号等信息。如果发现工程设置有误,则可以通过Back按钮返回前面的步骤,重新设置。检查无误后点击“Finish”,完成工程创建。
工程创建完成后的Vivado界面如图 1.3.7所示。
在这里插入图片描述

图 1.3.6 工程摘要界面
在这里插入图片描述

图 1.3.7 工程创建完成后的Vivado界面
step2:使用IP Integrator创建Processing System
Vivado开发套件中提供了一个图形化的设计开发工具——IP 集成器(IP Integrator),在IP集成器中可以非常方便的插入各种功能模块(IP)。它支持关键IP接口的智能自动连接、一键式IP子系统生成、实时DRC等功能,能够帮助我们快速组装复杂系统,加速设计流程。
接下来我们将在IP集成器中完成MPSOC嵌入式系统的搭建。
2-1 在左侧导航栏(Flow Navigator)中,单击IP Integrator下的Create Block Design。然后在弹出的对话框中指定所创建的Block Design的名称,这里使用默认的“design_1”。如下图所示:
在这里插入图片描述

图 1.3.8 创建 Block Design
2-2点击“OK”按钮,此时Vivado界面如下图所示。注意右侧的Diagram窗口,我们将在该窗口中以图形化的方式完成设计。
在这里插入图片描述

图 1.3.9 Block Design界面
2-3 接下来在Diagram窗口中给设计添加 IP。点击上图中箭头所指示的加号(两个任选一个)“+”,会打开IP目录(IP Catalog)。也可以通过快捷键Ctrl + I,或者右键点击Diagram工作区中的空白位置,然后选择“ADD IP”。
2-4 打开IP目录后,在搜索栏中键入“ZYNQ”,找到并双击“Zynq UltraScale+MPSOC”,将Zynq UltraScale+MPSOC IP添加到设计中。
在这里插入图片描述

图 1.3.10 添加Zynq UltraScale+MPSOC IP
2-5 添加完成后,Zynq UltraScale+MPSOC模块出现在Diagram中,如下图所示:
在这里插入图片描述

图 1.3.11 Zynq UltraScale+MPSOC IP
2-6 双击所添加的Zynq UltraScale+MPSOC模块,进入处理系统的配置界面。界面左侧为页面导航面板,右侧为配置信息面板。如下图所示:
在这里插入图片描述

图 1.3.12 Zynq UltraScale+MPSOC配置界面
下面我们简要地介绍一下页面导航面板中各个页面的作用。
PS UltraScale+ Block Design页面显示了zynq硬核的整体架构图,其中绿色部分是可配置模块,可以点击进入相应的编辑界面进行配置,当然也可以在左侧导航栏选择相应的编辑界面。
I/O Configuration页面可以选择不同的I/O外设并进行相应的配置。
Clock Configuration页面分为Input Clocks和Output Clocks两个标签页,用来配置PS输入时钟、外设时钟,以及DDR和CPU时钟等。
DDR Configuration页面用于设置DDR控制器配置信息。
PS-PL Configuration页面用于PS和PL交互的相关配置,包括常用的中断、复位信号和数据接口。
2-7 配置PS的UART。点击导航面板中I/O Configuration,出现以下页面:
在这里插入图片描述

图 1.3.13 配置MPSOC的UART
PS和外部设备之间的连接主要是通过复用的输入/输出(Multiplexed Input/Output,MIO)来实现的。PS的78个MIO引脚可以用于连接不同的外设接口。 UART引脚接口的选择需要与开发板对应,我们的MPSOC开发板PS端UART接口如下图所示:
在这里插入图片描述

图 1.3.14 开发板原理图
图 1.3.14是MPSOC开发板原理图的一部分。从图中我们可以看到,BANK501中的MIO42和MIO43被用作UART串口通信的引脚,并最终与开发板上的USB转串口芯片CH340连接。因此,为了实现串口通信的功能,我们需要在PS中将MIO42和MIO43配置成 UART0模块的接口引脚。
如下图所示,我们依次展开Low speed -> I/O Peripherals -> UART:
在这里插入图片描述

图 1.3.15 展开UART
勾选UART0,并在后面的IO栏中选择MIO42…43,如下图所示:
在这里插入图片描述

图 1.3.16 UART0的具体引脚配置
我们的MPSOC开发板bank500和bank502连接的是1.8V电压,bank501和bank503连接的是3.3V电压,所以将bank0和bank2电压设置为1.8V,bank1和bank3电压保持3.3V不变,如下图红圈1和2中所示。

在这里插入图片描述

图 1.3.17 bank电压设置
2-8 配置PS的DDR4控制器。
我们MPSOC开发板上PS端使用了4片Micron(镁光)DDR4芯片,型号是MT40A256M16GE-083E,容量为每片4Gbit(256M×16bit),总位宽为64bit(16bit×4),最高运行速度可达1200Mhz(数据速率2400Mbps)。
点击导航面板中的DDR Configuration选项,打开DDR配置页面。在Load DDR Presets选项中选择DDR4_MICRON_MT40A256MGE_083E,在弹出的Select an option对话框中,点击“Yes”确定;接着在DDR Controller Options一栏中,将Effective DRAM Bus Width设置为64bit;然后在DDR Memory Options一栏中,分别按下图红圈中所示设置:
在这里插入图片描述

图 1.3.18 配置PS的DDR控制器
2-9 配置PS的时钟。
点击左侧Clock Configuration打开时钟配置页面,该界面主要是配置MPSOC PS中的时钟频率。比如输入时钟默认是33.33333Mhz,这与我们开发板上的PS端输入时钟频率相同。对于CPU的时钟、DDR的时钟以及其它外设的时钟,我们直接保持默认设置即可。如下图所示:
在这里插入图片描述

图 1.3.19 配置PS的时钟
2-10 因为本实验是搭建MPSOC的嵌入式最小系统,只需要使用MPSOC中的PS端。因此我们将PS中与PL端交互的接口信号移除。
同样是在Clock Configuration页面,点击Output Clocks标签页,展开PL Fabric Clocks,取消勾选PL0,如下图所示:
在这里插入图片描述

图 1.3.20 去掉勾选PL0
点击左侧的PS-PL Configuration页面,然后在右侧展开General,取消勾选Fabric Reset Enable。
另外在当前页面中展开PS-PL interfaces,可以看到Master interface和Slave interface两项,展开Master interface,取消勾选其中的AXI HPM0 LPD。如下图所示:
在这里插入图片描述

图 1.3.21 取消勾选Fabric Reset Enable和AXI HPM0 LPD
2-11 配置ZYNQ UltraScale+ MPSOC完成,点击“OK”。
返回到Vivado界面后,在Diagram中可以看到ZYNQ UltraScale+ MPSOC IP模块发生了变化,如图 1.3.22所示。 我们将其与图 1.3.11作对比可以发现,该模块少了四组接口,这正是因为我们在配置该IP核的过程中移除了与PL相关的接口信号。
在这里插入图片描述

图 1.3.22 配置完成后的ZYNQ UltraScale+ MPSOC
2-12 我们点击下图中箭头所指示的按钮“validate design”,对我们配置的IP核进行验证,如下图所示:
在这里插入图片描述

图1.3.23 点击validate design检查IP核的配置
检查完成后没有错误,点击OK,按Ctrl+S保存,如下图所示:
在这里插入图片描述

图 1.3.24 检查完成
step3:生成顶层HDL模块
3-1 在Sources窗口中,选中Design Sources下的sysetm.bd, 这就是我们刚刚完成的Block Design设计。右键点击sysetm.bd,在弹出的菜单栏中选择“Generate Output Products”,如下图所示:
在这里插入图片描述

图1.3.25 选择Generate Output Products
3-2 弹出“Generate Output Products”对话框,如下图所示:
在这里插入图片描述

图1.3.26 设置Generate选项
在对话框中,Synthesis Options选择Out of context per IP,这里我们保持默认;Run Setings用于设置生成过程中要使用的处理器的线程数,进行多线程处理,保持默认或设置为个人电脑处理器最大可使用线程数都可以,一般选择最大可使用线程数。然后点击“Generate”来生成设计的综合、实现和仿真文件。
在“Generate”过程中会为设计生成所有需要的输出结果。比如Vivado工具会自动生成处理系统的XDC约束文件,因此我们不需要手动对MPSOC PS引出的接口(DDR和FIXED_IO)进行管脚分配。
Generate完成后,在弹出的对话框中点击“OK”。
在Sources窗口中,点击“IP Source”标签页,可以看到Generate过程生成的输出结果。
在这里插入图片描述

图1.3.27 block design生成的结果
3-3 在“Hierarchy”标签页再次右键点击system.bd,然后选择“Create HDL Wrapper”。
在这里插入图片描述

图1.3.28 生成顶层模块
在弹出的对话框中确认勾选“Let Vivado manage wrapper and auto-update”,然后点击“OK”。
在这里插入图片描述

图 1.3.29 创建顶层HDL封装
创建完成后,Design Sources结构如下图所示:
在这里插入图片描述

图1.3.30 生成design_1_wrapper.v顶层文件
design_1_wrapper.v为创建的Verilog文件,箭头所指的“品”字形图标指示当前模块为顶层模块。该模块使用Verilog HDL对设计进行封装,主要完成了对block design的例化,大家也可以双击打开该文件查看其中的内容。
另外我们在图1.3.29中勾选了“Let Vivado manage wrapper and auto-update”,这样我们在修改了Block Design之后就不需要再重新生成顶层模块,Vivado工具会自动更新该文件。
step4:生成Bitstream文件并导出Hardware
如果设计中使用了PL的资源,则需要添加引脚约束并对该设计进行综合、实现并生成Bitstream文件。由于本次实验未用到PL部分,所以无需生成Bitstream文件,只需将硬件导出即可。
4-1 导出硬件。
在菜单栏选择 File > Export > Export hardware。
在这里插入图片描述

图1.3.31 导出硬件
在弹出的对话框中,因为没有生成bitstream文件,所以无需勾选“Include bitstream”,直接点击“OK”按钮。
在这里插入图片描述

图1.3.32 无需勾选“Include bitstream”
上图中,XSA file name一栏是产生的硬件信息文件的文件名,这里我们保持默认。Export to后面的路径是生成的包含硬件信息文件的路径,生成的文件如下所示:
在这里插入图片描述

图 1.3.33 生成的xsa文件
4-2 硬件导出完成后,我们在工程路径下新建一个名为vitis的文件夹,用于存放vitis的工程,同时将design_1_wrapper.xsa文件拷贝进去,如下图所示:
在这里插入图片描述

图1.3.34 将xsa文件拷贝到vitis文件夹下
在菜单栏中选择Tools > Launch Vitis,启动Vitis开发环境。如下图所示:
在这里插入图片描述

图1.3.35 启动Vitis开发环境
在弹出的对话框中,我们将工程路径指定到新建的vitis文件夹下,如下图所示:
在这里插入图片描述

图1.3.36 设置工作空间
到这里,我们已经完成了MPSOC嵌入式系统的硬件设计部分。接下来需要到Vitis软件中进行应用程序开发,也就是软件设计部分。
1.4软件设计
在硬件设计的最后,我们启动了软件开发环境(Vitis),如下图所示:
在这里插入图片描述

图 1.4.1 Vitis开发环境界面
step5:在Vitis中创建应用工程
5-1 在菜单栏选择File > New > Application Project, 新建一个vitis应用工程,如下图所示:
在这里插入图片描述

图 1.4.2 新建应用工程
5-2 在弹出的对话框中,输入工程名“hello_world”,其它选项保持默认即可,点击“Next”,如下图所示:
在这里插入图片描述

图 1.4.3 配置工程
5-3 打开Create a new platform from hardware(XSA)标签页,点击“+”添加xsa文件,如下图所示:
在这里插入图片描述

图1.4.4 添加xsa文件
在弹出的窗口中选择design_1_wrapper.xsa文件,如下图所示:
在这里插入图片描述

图 1.4.5 选择design_1_wrapper.xsa文件
添加xsa文件后的页面如下图所示,点击next:
在这里插入图片描述

图 1.4.6 添加完成xsa文件
5-4 在弹出的页面中有一个Generate boot components选项,如果勾选,软件会自动生成fsbl工程,这里我们选择默认勾选,然后点击next,如下图所示:
在这里插入图片描述

图1.4.7 默认生成fsbl工程
5-5 在弹出的工程模板选择页面里,我们选择已有的Hello World模板,然后点击Finish,如下图所示:
在这里插入图片描述

图 1.4.8 选择Hello World模板
工程建立完成后的页面如下图所示,我看可以看到生成了两个工程,一个是硬件平台工程,即platform工程,一个是应用工程。
在这里插入图片描述

图 1.4.9 工程建立完成
5-6 双击打开hello_world/src工程目录下helloworld.c文件,可以看到源代码如下:

1  #include <stdio.h>
2  #include "platform.h"
3  #include "xil_printf.h"
4  
5  int main()
6  {
7      init_platform();
8  
9      print("Hello World\n\r");
10 
11     cleanup_platform();
12     return 0;
13 }

可以看到程序中主函数调用了3个函数,分别是init_platform()、cleanup_platform()和print()函数。我们将鼠标停留在各个函数名上,vitis就会显示该函数的声明。如果想查看函数的定义,可以按住Ctrl键不放,用鼠标点击相应的函数,就会跳转到其定义的地方。
init_platform和cleanup_platform函数定义如下:
在这里插入图片描述

图 1.4.10 init_platform和cleanup_platform函数定义
可以看到init_platform函数的作用是使能caches和初始化uart;cleanup_platform函数的作用是取消使能caches。实际上这两个函数在该工程中并没有启动任何作用,因为这两个函数是针对于特定平台如Microblaze的,对于我们使用的MPSOC平台而言是不起作用的,所以main函数中只需包含第9行的print语句就可以了,出于平台的通用性和可移植性,此处我们保留这两个函数。
另外需要注意程序中打印字符串“Hello World”使用的是print()函数,而不是C语言里的printf()函数。print()函数是Xilinx定义的一个用于打印字符串的函数,调用该函数需要包含头文件“xil_printf.h”。
5-7 选中应用工程,右键Build Project对工程进行编译。
在这里插入图片描述

图 1.4.11 编译工程
编译进度可以在工具下方的控制台面板(Console)中进行查看,编译完成后显示“Finished building:hello_world.elf”,如下图所示:
在这里插入图片描述

图 1.4.12 编译完成
到这里我们已经完成了本次实验的软件设计部分。
1.5下载验证
首先我们将下载器与MPSOC开发板上的JTAG接口连接,下载器另外一端与电脑连接。然后使用USB连接线将开发板USB_UART (PS_PORT)接口与电脑连接,用于串口通信。接下来将开发板上四个启动模式开关均置为ON,即设置为JTAG模式。最后连接开发板电源给开发板上电。如下图所示:
在这里插入图片描述

图 1.5.1 MPSOC开发板实物图
注意第一次连接开发板USB_UART接口时,需要安装USB串口驱动。在开发板随附的资料中找到“6_软件资料/1_软件/CH340驱动(USB串口驱动)”文件夹,双击打开文件夹中的“SETUP.EXE”进行安装,驱动安装界面如下图所示。界面中提示INF文件为CH341SER.INF,我们不需要理会(CH341,CH340驱动是共用的),直接点安装即可。
在这里插入图片描述

图 1.5.2 安装USB串口驱动
step6:板级验证
6-1 在Vitis软件的下方,找到Terminal窗口。如果界面中没有找到该窗口,或者操作过程中把该窗口给关闭了,则可以通过在菜单栏中选择Window > Show View > Other,在Show View窗口中搜索添加Terminal。
在这里插入图片描述

图 1.5.3 搜索添加Terminal
点击Open添加Terminal:
在这里插入图片描述

图 1.5.4 添加Terminal
添加Terminal后如下图所示,点击箭头处的图标对串口进行设置。
在这里插入图片描述

图1.5.5 Vitis自带的Terminal终端
在弹出的窗口中,Choose terminal一栏中,下拉选择Serial Terminal串口终端,如下图所示:

在这里插入图片描述

图1.5.6 选择串口终端
选择串口终端后,接下来需要对串口设置。这里设置波特率为 “115200”,数据位为8位,停止位为1位,然后点击OK,如下图所示:
在这里插入图片描述

图1.5.7 配置串口终端
配置完成,连接成功后如下图所示:
在这里插入图片描述

图1.5.8 串口连接成功
需要注意的是,在设置串口端口(Port)时,在下拉列表中可能会看到多个可选端口。我们需要选择与开发板上的串口所连接的端口,具体的端口号可在计算机设备管理器中查看。因为开发板上使用的USB转串口芯片型号为CH340,因此在设备管理器中找到USB-SERIAL CH340所对应的端口,在我这台电脑上该端口号为COM3,如下图所示:
在这里插入图片描述

图 1.5.9 查看串口端口
6-2 下载程序。右键点击hello_world工程,选择“Run As”,然后选择最后一项“Run Confagurations…”,如下图所示:
在这里插入图片描述

图 1.5.10 打开下载页面
在打开的下载页面中,没有出现下载选项,这时需要双击左侧列表中Single Application Debug一项,双击后,该项下面出现新的项Debugger_hello_world-default,同时在右侧出现的页面中选择Target Setup标签页,勾选复位,然后点击run下载程序,如下图所示:

在这里插入图片描述

图1.5.11 下载程序
6-3 下载完成后,应用程序会将字符串“Hello World”通过MPSOC PS端的串口模块发送出去。在Terminal窗口可以看到上位机接收到的字符串,如下图所示:
在这里插入图片描述

图 1.5.12 程序运行结果
程序成功打印出了“Hello World”字符串,说明本次实验在MPSOC开发板上面下载验证成功。