1)实验平台:正点原子MPSoC开发板
2)平台购买地址:https://detail.tmall.com/item.htm?id=692450874670
3)全套实验源码+手册+视频下载地址: http://www.openedv.com/thread-340252-1-1.html
PS和外部设备之间的通信主要是通过复用的输入/输出(Multiplexed Input/Output,MIO)实现的。除此之外,PS还可以通过扩展的MIO(Extended MIO,EMIO)来实现与外部设备的连接。EMIO使用了PL的I/O资源,当PS需要扩展超过78个引脚的时候可以用EMIO,也可以用它来连接PL中实现的IP模块。
本章我们将学习GPIO中EMIO接口信号的使用。本章包括以下几个部分:
33.1简介
3.2实验任务
3.3硬件设计
3.4软件设计
3.5下载验证
MPSOC GPIO接口信号被分成六组,分别是从BANK0到BANK5。其中BANK0, BANK1和BANK2共计78个信号通过MIO连接到MPSOC器件的引脚上,这些引脚属于PS端;而BANK3,BANK4和BANK5中共计96个信号则通过EMIO连接到了MPSOC器件的PL端。如下图所示:
图 3.1.1 GPIO框图
在大多数情况下,PS端经由EMIO引出的接口会直接连接到PL端的器件引脚上,通过IO管脚约束来指定所连接PL引脚的位置。通过这种方式,EMIO可以为PS端实现额外的96个输入引脚或96个带有输出使能的输出引脚。EMIO还有一种使用方式,就是用于连接PL内实现的功能模块(IP核),此时PL端的IP作为PS端的一个外部设备。
3.2实验任务
本章的实验任务是使用MPSOC开发板上的两个PS端按键控制PL端LED亮灭,两个PL端按键去控制PS端LED的亮灭。
3.3硬件设计
根据实验任务我们可以画出本次实验的系统框图,如下图所示:
图 3.3.1 系统框图
与《GPIO之MIO控制LED实验》中的系统框图相比,图 3.3.1中的PS端多了EMIO模块。除此之外,因为EMIO使用了PL端的IO资源,所以图中增加了PL部分。PL端与按键和LED相连的引脚直接通过EMIO连接到PS端。
step1:创建Vivado工程
本次实验可以在前一个实验的基础上进行。
1-1 我们打开《GPIO之MIO控制LED实验》中的Vivado工程“gpio_mio”,打开后在菜单栏中选择File > Project > Save As,如下图所示:
图 3.3.2 选择另存为
1-2 在弹出的对话框中输入新的工程名,在Project name一栏输入工程名“gpio_emio”,工程位置保持默认即可,如下图所示:
图 3.3.3 工程另存为
点击“OK”按钮,原先的Vivado工程会关闭,并打开一个新的工程“gpio_emio”。
此时如果我们打开工程所在的路径,即F:\ZYNQ\Embedded_System\gpio_emio,可以看到如下图所示的文件目录:
图 3.3.4 gpio_emio工程目录
此时我们就在gpio_mio工程的基础上得到了一个新的工程gpio_emio,这样就省去了重新搭建硬件的过程。
接下来我们将在《GPIO之MIO控制LED实验》中硬件设计的基础上搭建本次实验的硬件平台。
step2:使用IP Integrator创建Processing System
2-1在Flow Navigator中,点击IP INTEGRATOR下的Open Block Design,如下图所示:
图 3.3.5 打开Block Design
2-2 在Diagram窗口中,双击打开Zynq UltraScale+ MPSoC重定义窗口。
图 3.3.6 重定义Zynq UltraScale+ MPSoC
2-3 在下图所示的配置界面中,点击左侧的I/O Configuration。然后在右侧展开GPIO一栏,勾选GPIO EMIO,并设置位宽为4。该设置将通过EMIO扩展一个4位的GPIO接口信号,此信号将用于连接PL端的引脚。注意这里GPIO0和GPIO1已经勾选。
图 3.3.7 勾选GPIO EMIO
完成配置后,点击右下角的“OK”按钮。然后在Diagram窗口中可以看到Zynq UltraScale+ MPSoC多了一个GPIO_0端口,如下图所示:
图 3.3.8 通过EMIO引出的GPIO接口
将光标移动到上图中箭头所指示的位置,会发现光标变成了铅笔的样式。点击选中该端口,然后点击鼠标右键,在弹出的列表中选择“Make External”。如下图所示:
图 3.3.9 Make External
可以看到Zynq UltraScale+ MPSoC引出了一个名为GPIO_0_0的接口,如下图所示:
图 3.3.10 引出的GPIO接口
点击选中该接口,在左侧External Interface Properties一栏中将该接口的名称修改为GPIO_EMIO。如下图所示:
图 3.3.11 修改接口名称
2-4 本次实验不需要添加其它的IP,按Ctrl+S快捷键保存设计。
step3:生成顶层HDL
3-1 在Sources窗口中展开Design Sources,然后右键点击design_1_wrapper下的design_1.bd,在弹出的菜单中选择Generate Output Products,如下图所示:
图 3.3.12 选择Generate Output Products
3-2 在弹出的对话框中选择“Generate”,然后等待Generate完成后点击“OK”。
3-3 创建顶层HDL Wrapper
在之前的实验中,我们创建顶层模块时选择了“Let Vivado manage wrapper and auto-update”选项,所以此处无需再创建顶层HDL Wrapper,Vivado会自动更新顶层HDL Wrapper。
step4:生成Bitstream文件并导出Hardware
4-1在左侧Flow Navigator导航栏中找到RTL ANALYSIS,点击该选项中的“Open Elaborated Design”。如下图所示:
图 3.3.13 打开详细设计
在弹出的对话框中点击“OK”。如下图所示:
图 3.3.14 Elaborate Design 对话框
在ELABORATED DESIGN界面下方找到I/O Ports窗口。如果没有找到I/O Ports一栏则通过在菜单栏中点击Layout,然后在下拉列表中选择I/O Planning。我们将在I/O Ports窗口中对PL部分的接口进行管脚分配。PS端的管脚约束文件,在图 3.3.12中选择“Generate Output Products”之后,Vivado工具会自动创建。
图 3.3.15 I/O ports窗口
在本次实验中,我们通过EMIO扩展了四个GPIO的接口信号,即上图中的GPIO_EMIO_tri_io[0],GPIO_EMIO_tri_io[1],GPIO_EMIO_tri_io[2],GPIO_EMIO_tri_io[3]。这里,我们将GPIO_EMIO_tri_io[0]接到PL_KEY1引脚,GPIO_EMIO_tri_io[1]接到PL_KEY2引脚,GPIO_EMIO_tri_io[2]接到PL_LED1引脚,GPIO_EMIO_tri_io[3]接到PL_LED2引脚。
查看原理图可知,这四个引脚的管脚约束分别是,PL_KEY1为AD11,PL_KEY2为AD10,PL_LED1为AE10,PL_LED2为AF10,且都在BANK44上,该BANK电压为3.3V。接下来在软件中进行管脚分配,I/O Std一列对应的电平也需要修改。如下图所示:
图 3.3.16 管脚分配
4-2设置完成后按快捷Ctrl+S保存管脚约束,在弹出的对话框输入文件名“pin”,最后点击“OK”,如下图所示:
图 3.3.17 保存约束
4-3在左侧Flow Navigator导航栏中找到PROGRAM AND DEBUG,点击该选项中的“Generate Bitstream”,然后在连续弹出的对话框中依次点击“YES”、“OK”。此时,Vivado工具开始对设计进行综合、实现、并生成Bitstream文件。
4-4 生成Bitstream完成后,在弹出的对话框中选择“Open Implemented Design”,如下图所示:
图 3.3.18 打开实现后的设计
点击“OK”,如果弹出对话框提示关闭Elaborated Design,则点击“YES”。
在IMPLEMENTED DESIGN界面我们可以查看设计对PL资源的使用情况。在左侧Flow Navigator导航栏中找到IMPLEMENTATION,点击该选项中的“Report Utilization”,然后在弹出的对话框中点击“OK”。如下图所示:
图 3.3.19 报告资源使用情况
在界面下方的Utilization标签页中,选择左侧的Summary,然后在右侧会以表格和柱状图两种方式显示当前PL资源的使用情况。在我们本次实验中,只消耗了PL端4个LUT和4个IO资源,这个IO就是PS通过EMIO扩展GPIO接口信号时所使用的PL引脚。如下图所示:
图 3.3.20 资源使用总结报告
4-5 导出硬件。
在菜单栏中选择 File > Export > Export hardware。
在弹出的对话框中,勾选“Include bitstream”,然后点击“OK”按钮。如下图所示:
图 3.3.21 勾选“Include bitstream”
在此处需要注意,如果我们的设计使用了PL的资源,比如使用了PL的引脚,或者在PL内实现了部分功能模块,那么我们就需要生成Bitstream文件,并在导出硬件的时候包含该文件。
4-6 新建vitis文件夹,将生成的xsa文件移到里面。
4-7 硬件导出完成后,在菜单栏选择Tools > Launch Vitis,启动Vitis开发环境。在弹出的对话框中,将路径指定到新建的vitis文件夹下,点击Launch启动Vitis。
到这里我们的硬件设计部分已经结束,接下来的软件设计部分需要在Vitis软件中进行。
3.4软件设计
在硬件设计的最后,我们打开了Vitis开发环境,下面我们开始第五步——创建应用工程。
step5:在Vitis中创建应用工程
5-1在菜单栏依次点击“File->New->Application Project”,新建一个Vitis应用工程。在弹出的对话框中,输入工程名“gpio_emio”,其他默认,点击“Next”,如下图所示:
图 3.4.1 创建工程
5-2 点击“Create a new platform hardware(XSA)”,软件提供了一些板卡的硬件平台以供选择,但对于我们自己的硬件平台需要手动添加,点击“+”添加。
图 3.4.2 添加硬件平台
选择vitis文件夹下的“design_1_wrapper.xsa”,如下图所示。
图 3.4.3 选择硬件平台文件
成功添加我们自己的硬件平台后,点击next,如下图所示:
图 3.4.4 硬件平台添加完成
5-3弹出的页面中保持默认设置,点击next。
图 3.4.5 保持默认设置
5-4选择工程模版“Empty Application”,本章将自行创建工程文件,故选择空模板,然后点击“Finish”按钮,如下图所示:
图 3.4.6 选择工程模板
5-5 新建源文件。首先我们在gpio_emio/src目录上右键,选择New-> File,如下图所示:
图 3.4.7 新建源文件
在弹出的对话框中File name一栏输入文件名“main.c”,然后点击“Finish”。
图3.4.8 输入文件名
5-6 输入源代码。我们在新建的main.c文件中输入以下代码:
1 #include "stdio.h"
2 #include "xparameters.h"
3 #include "xgpiops.h"
4
5 #define GPIOPS_ID XPAR_XGPIOPS_0_DEVICE_ID //PS端 GPIO器件 ID
6
7 #define MIO_LED1 38 //PS_LED1 连接到 MIO38
8 #define MIO_LED2 39 //PS_LED2 连接到 MIO39
9 #define MIO_KEY1 40 //PS_KEY1 连接到 MIO40
10 #define MIO_KEY2 41 //PS_LEY2 连接到 MIO41
11 #define EMIO_KEY1 78 //PL_KEY1 连接到 EMIO0
12 #define EMIO_KEY2 79 //PL_KEY2 连接到 EMIO1
13 #define EMIO_LED1 80 //PL_LED1 连接到 EMIO2
14 #define EMIO_LED2 81 //PL_LED2 连接到 EMIO3
15
16 int main()
17 {
18 printf("EMIO TEST!\n");
19
20 XGpioPs gpiops_inst; //PS端 GPIO 驱动实例
21 XGpioPs_Config *gpiops_cfg_ptr; //PS端 GPIO 配置信息
22
23 //根据器件ID查找配置信息
24 gpiops_cfg_ptr = XGpioPs_LookupConfig(GPIOPS_ID);
25 //初始化器件驱动
26 XGpioPs_CfgInitialize(&gpiops_inst,gpiops_cfg_ptr,gpiops_cfg_ptr->BaseAddr);
27
28 //设置LED为输出
29 XGpioPs_SetDirectionPin(&gpiops_inst, MIO_LED1, 1);
30 XGpioPs_SetDirectionPin(&gpiops_inst, MIO_LED2, 1);
31 XGpioPs_SetDirectionPin(&gpiops_inst, EMIO_LED1, 1);
32 XGpioPs_SetDirectionPin(&gpiops_inst, EMIO_LED2, 1);
33 //使能LED输出
34 XGpioPs_SetOutputEnablePin(&gpiops_inst, MIO_LED1, 1);
35 XGpioPs_SetOutputEnablePin(&gpiops_inst, MIO_LED2, 1);
36 XGpioPs_SetOutputEnablePin(&gpiops_inst, EMIO_LED1, 1);
37 XGpioPs_SetOutputEnablePin(&gpiops_inst, EMIO_LED2, 1);
38
39 //设置KEY为输入
40 XGpioPs_SetDirectionPin(&gpiops_inst, MIO_KEY1, 0);
41 XGpioPs_SetDirectionPin(&gpiops_inst, MIO_KEY2, 0);
42 XGpioPs_SetDirectionPin(&gpiops_inst, EMIO_KEY1, 0);
43 XGpioPs_SetDirectionPin(&gpiops_inst, EMIO_KEY2, 0);
44
45 //读取按键状态,控制LED亮灭
46 while(1){
47 XGpioPs_WritePin(&gpiops_inst, MIO_LED1,
48 ~XGpioPs_ReadPin(&gpiops_inst, EMIO_KEY1));
49
50 XGpioPs_WritePin(&gpiops_inst, MIO_LED2,
51 ~XGpioPs_ReadPin(&gpiops_inst, EMIO_KEY2));
52
53 XGpioPs_WritePin(&gpiops_inst, EMIO_LED1,
54 ~XGpioPs_ReadPin(&gpiops_inst, MIO_KEY1));
55
56 XGpioPs_WritePin(&gpiops_inst, EMIO_LED2,
57 ~XGpioPs_ReadPin(&gpiops_inst, MIO_KEY2));
58
59 }
60
61 return 0;
62 }
在代码的第7至10行,我们指定了PS端输出LED和输入KEY的MIO编号,这些编号可以从MPSOC开发板的原理图中查到。在代码的11至14行指定了PL端LED和按键KEY的EMIO编号,那么这些编号是怎么来的呢?
在本章的简介部分我们提到过,MPSOC的GPIO被分成了6组,其中通过EMIO扩展的GPIO接口位于BANK3至BANK5中,如图 3.1.1所示。在本次实验中我们通过EMIO扩展了4个GPIO信号,即BANK3的EMIO0,EMIO1,EMIO2,EMIO3,由于GPIO的BANK0,BANK1,BANK2分别有26个信号,即MIO共有78个信号,所以BANK3的EMIO0是第79个信号,编号为78(从0开始编号)。
我们按住Ctrl键,然后点击代码开头处所引用的头文件“xgpiops.h”以打开该文件。
在xgpiops.h文件第162行给出了MPSOC器件GPIO最大的引脚数目,共174个,分别位于6个Bank中。在下面的注释中则分别列出了各Bank的引脚编号范围,同样可以看到Bank3的第一个引脚编号为78。
图3.4.9 GPIO引脚编号
在程序的第46至59行,我们在一个死循环中不断读取各按键的状态,然后将读到的值取反后分别写入对应的LED中,从而实现按键控制LED的功能。从上面的程序中大家也可以看出,通过EMIO扩展的GPIO接口的使用方法和MIO没有任何区别。如果大家对GPIO的使用不熟悉的话,请参考《GPIO之MIO控制LED实验》。
5-7 编译工程。保存main.c文件,右键点击应用工程gpio_emio,在弹出的菜单中选择Build Project,如下图所示:
图3.4.10 编译工程
工程编译结束后,在Binaries下成功生成gpio_emio.elf文件。
至此,硬件和软件设计部分均已完成。
3.5下载验证
完成了硬件设计和软件设计后,我们就可以进行板级验证了,也就是设计流程的最后一步。在进行板级验证之前,我们先将开发板上的JTAG与电脑连接,然后使用USB连接线将USB UART(PS_PORT)接口与电脑连接,然后连接开发板的电源,给开发板上电。
step6:板级验证
6-1 打开串口助手或具有串口功能的软件。串口助手是上位机中用于辅助串口调试的小工具,可以选择安装使用开发板随附资料中“6_软件资料/1_软件/ XCOM V2.0”的文件夹中提供的串口助手,也可从网上下载或选择自己常用的串口调试工具。这里我们使用Vitis软件自带的串口终端。
按照《Hello World》实验中的步骤,打开Vitis中的Terminal窗口,如下图所示:
图 3.5.1 打开Vitis串口终端
我们进入该窗口后,点击上图箭头所指的图标,在弹出的窗口中对串口进行设置,选择串口“Serial Terminal”,COM口依据自己的电脑设置,波特率为“115200”,数据位为8位,停止位为1位,如下图所示:
图 3.5.2 设置UART串口
点击“OK”,串口终端成功连接,如下图所示:
图 3.5.3串口连接成功
6-2 下载程序。右键选择gpio_emio工程,在弹出的菜单中选择Run as-> Launch on Hardware,如下图所示:
图 3.5.4 下载程序
这里需要注意一下,通过Run As->Launch on Hardware下载可以将bit文件和elf文件一块下载,不需要分别下载。
软件程序下载完成后,在下方的Terminal中可以看到应用程序打印的信息“EMIO TEST!”,如下图所示:
图 3.5.5 串口终端中打印的信息
我们按下开发板上的两个PS端的用户按键PS_KEY1和PS_KEY2,可以看到对应的两个PL端LED灯PL_LED1和PL_LED2分别点亮。
然后再按下两个PL端的用户按键PL_KEY1和PL_KEY2,可以看到对应的PS端的LED灯PS_LED1和PS_LED2分别点亮。说明我们通过EMIO扩展GPIO接口,按键控制LED灯实验验证成功。实验结果如下图所示:
图 3.5.6 下载验证