Xilinx-ZYNQ7000系列-学习笔记(5):设置EMIO并固化到QSPI
一、EMIO的设置
预先知识
MIO:多功能IO接口,属于Zynq的PS部分,在芯片外部有54个引脚。这些引脚可以用在GPIO、SPI、UART、TIMER、Ethernet、USB等功能上,每个引脚都同时具有多种功能,故叫多功能。
EMIO:扩展MIO,依然属于Zynq的PS部分,只是连接到了PL上,再从PL的引脚连到芯片外面实现数据输入输出
配置方法
1.创建Block块并添加ZYNQ系统IP核:
(1)由于要配置PL端的LED,所以要将EMIO的对勾选上
(2)由于后期要进行QSPI固化,所以这里要将QSPI也选上,并将下面都变为fast
(3)由于这里要点亮8盏LED灯,所以需要8位EMIO,这里将宽度设为8
这里要注意一下:只有当设置了EMIO范围内的管脚才能在SDK中使用,例如在这里定义了EMIO宽度为4,则在SDK中只能使用EMIO54,55,56,57。
(4)改变DDR型号
(5)完成更改,回到block design中看看,发现多出了GPIO_0。选中它将引脚引出。这里的GPIO_0对应EMIO。(做法:右键GPIO_0选make external)
(6)导出和生成顶层文件(这里不多介绍)
2.添加引脚约束文件:
所有PL端属于FPGA部分,所以必须添加XDC约束文件;而PS端是ARM部分,不用添加也可以。
注意这里的端口名称一定要和顶层文件中的定义端口名称一致。
3.导入到SDK:
生成bit流之后,导入到SDK中,切记如果有PL部分,一定要将bit流一起导入过去。
(1)file->export->export hardware
(2)file ->lauch SDK
4.建立工程:
(1)file->new->Application Project->(随便起个名字)建立好是这样的
(2)将代码输入到helloworld.c文件中,代码如下:
/*
* main.c
*
* Created on: 2018年7月30日
* Author: zxc
*/
#include "xgpiops.h"
#include "sleep.h"
#include "xparameters.h"
int main()
{
XGpioPs gpioStruct;
XGpioPs_Config *gpioConfig;
int pinNum1 = 54;
int pinNum2 = 55;
int pinNum3 = 56;
int pinNum4 = 57;
int pinNum5 = 58;
int pinNum6 = 59;
int pinNum7 = 60;
int pinNum8 = 61;
u32 pinDirection = 1; //1表示输出, 0表示输入
s32 xStatus;
print("hello\n");
//初始化MIO
//通过gpio的device_ID获取GPIO寄存器的基地址
gpioConfig = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);
if(gpioConfig == NULL) //若指针为空,说明没有找到对应的设备或者FPGA底层未进行配置
{
print("Can not lookup gpioConfig!!!\n");
return XST_FAILURE;
}
//初始化GPIO
xStatus = XGpioPs_CfgInitialize(&gpioStruct, gpioConfig, gpioConfig->BaseAddr);
if(xStatus != XST_SUCCESS)
{
print("PS MIO GPIO Initialize failed!!!\n");
}
else
{
print("PS MIO GPIO Initialize successed!!!\n");
}
//设置GPIO的引脚以及输入输出模式
XGpioPs_SetDirectionPin(&gpioStruct, pinNum1, pinDirection);
//设置GPIO的输出使能
XGpioPs_SetOutputEnablePin(&gpioStruct, pinNum1, 1);
XGpioPs_SetDirectionPin(&gpioStruct, pinNum2, pinDirection);
//设置GPIO的输出使能
XGpioPs_SetOutputEnablePin(&gpioStruct, pinNum2, 1);
XGpioPs_SetDirectionPin(&gpioStruct, pinNum3, pinDirection);
//设置GPIO的输出使能
XGpioPs_SetOutputEnablePin(&gpioStruct, pinNum3, 1);
XGpioPs_SetDirectionPin(&gpioStruct, pinNum4, pinDirection);
//设置GPIO的输出使能
XGpioPs_SetOutputEnablePin(&gpioStruct, pinNum4, 1);
XGpioPs_SetDirectionPin(&gpioStruct, pinNum5, pinDirection);
//设置GPIO的输出使能
XGpioPs_SetOutputEnablePin(&gpioStruct, pinNum5, 1);
XGpioPs_SetDirectionPin(&gpioStruct, pinNum6, pinDirection);
//设置GPIO的输出使能
XGpioPs_SetOutputEnablePin(&gpioStruct, pinNum6, 1);
XGpioPs_SetDirectionPin(&gpioStruct, pinNum7, pinDirection);
//设置GPIO的输出使能
XGpioPs_SetOutputEnablePin(&gpioStruct, pinNum7, 1);
XGpioPs_SetDirectionPin(&gpioStruct, pinNum8, pinDirection);
//设置GPIO的输出使能
XGpioPs_SetOutputEnablePin(&gpioStruct, pinNum8, 1);
while(1){
XGpioPs_WritePin(&gpioStruct, pinNum1, 1); //给高电平
usleep(1000*500);
XGpioPs_WritePin(&gpioStruct, pinNum2, 1); //给高电平
usleep(1000*500);
XGpioPs_WritePin(&gpioStruct, pinNum3, 1); //给高电平
usleep(1000*500);
XGpioPs_WritePin(&gpioStruct, pinNum4, 1); //给高电平
usleep(1000*500);
XGpioPs_WritePin(&gpioStruct, pinNum5, 1); //给高电平
usleep(1000*500);
XGpioPs_WritePin(&gpioStruct, pinNum6, 1); //给高电平
usleep(1000*500);
XGpioPs_WritePin(&gpioStruct, pinNum7, 1); //给高电平
usleep(1000*500);
XGpioPs_WritePin(&gpioStruct, pinNum8, 1); //给高电平
usleep(1000*500);
}
return 0;
}
(3)由于数据中带有PL部分,所以我们需要将这两个选项也选上。
烧进去程序以后我们会发现灯循环点亮。
二、程序的固化处理
要想了解板子的启动详细步骤与说明请参考
不废话,直接开始固化过程:
(1)进入SDK 开发环境后,点击菜单 File -> New -> Application Project。
(2)仅在 Project name: 输入 fsbl,Hardware Platform 需要选择system_wrapper_hw_platform_0。
next,选择 Zynq FSBL 模板
(3)右键你自己的工程文件选择Board Support Package Setting,选择xilffs和xilrsa加入,点击OK。
(4)在工程目录下新建boot文件夹,用来存储BOOT文件。
(5)点击Xilinx Tools->Creat Boot Image选择bif和BIN文件的输出位置为你刚才设定的文件夹。
(6)在Boot image partitions中点击Add,依次添加fsbl文件、bit文件和应用程序.elf文件。这里要说明一下三个文件:
1.FSBL文件夹中的elf文件,从而将fsbl启动任务添加进去。
2.你的工程文件夹中的bit文件,从而将PL部分添加进去。
3.你的工程文件夹中的elf文件,从而将SDK中的控制逻辑加进去。
(7)点击Creat Image后,会在boot文件夹下生成.bif文件和.bin文件。
(8)(这一步为选做),有些板子可以直接下载BOOT文件,但是有些需要生成MCS文件,接下来是将BOOT文件转为MCS文件。
(9)把.mcs镜像文件烧写入Flash中。
(10)选择镜像文件,点击Program。