ZYNQ EMIO使用及可重用封装
为了快速实现算法板级验证,PC端需要通过JTAG或以太网与FPGA形成通路。最简单便捷的方案是利用协议栈芯片,用户可以无视底层,利用简单的SPI协议读写寄存器实现复杂的TCP UDP等网络协议。当然带宽会受限于SPI接口有效速率,本文采用芯片为W5500,支持10M/100M自适应,其理论值高达80Mbps,基本达到算法验证的要求。
ZYNQ可以通过灵活的EMIO模拟SPI接口,从而在最少改动官方demo的前提下移植C语言驱动程序。本文着重讲述EMIO的C语言软件驱动方式及可重用封装,封装后可以接口方式被其他应用程序直接调用,非常方便。直接上代码,再加以说明。
/*
* EMIO_ope.c
*
*/ #include "xgpiops.h"
#include "xparameters.h"
#include "xstatus.h"
#include "W5500.h"
#include "EMIO_ope.h" static XGpioPs psGpioInstancePtr; int EMIO_init()
{
XGpioPs_Config* GpioConfigPtr;
int xStatus; //--EMIO的初始化
GpioConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID);
if(GpioConfigPtr == NULL)
return XST_FAILURE; xStatus = XGpioPs_CfgInitialize(&psGpioInstancePtr,GpioConfigPtr, GpioConfigPtr->BaseAddr);
if(XST_SUCCESS != xStatus)
print(" PS GPIO INIT FAILED \n\r"); //--EMIO的输入输出操作
XGpioPs_SetDirectionPin(&psGpioInstancePtr, ETH_NRST_BASE,);
XGpioPs_SetDirectionPin(&psGpioInstancePtr, USER_SPI_MOSI_BASE,);
XGpioPs_SetDirectionPin(&psGpioInstancePtr, USER_SPI_CSN_BASE,);
XGpioPs_SetDirectionPin(&psGpioInstancePtr, USER_SPI_SCLK_BASE,);
XGpioPs_SetDirectionPin(&psGpioInstancePtr, USER_SPI_MISO_BASE,); //使能输出端口
XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, ETH_NRST_BASE,);
XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, USER_SPI_MOSI_BASE,);
XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, USER_SPI_CSN_BASE,);
XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, USER_SPI_SCLK_BASE,); return xStatus;
} void writePin(u32 pinNum,u32 value)
{
XGpioPs_WritePin(&psGpioInstancePtr, pinNum, value);
} u32 readPin(u32 pinNum)
{
return XGpioPs_ReadPin(&psGpioInstancePtr,pinNum);
}
Xilinx封住的库函数有其固定的“套路”。首先查找设备配置,初始化。之后设置EMIO的方向,如果是输出方向还要使能输出。这里将上述预处理部分封装到EMIO_Init()函数中。之后再编写两个函数分别实现EMIO寄存器的读和写,也就是读取输入接口数据以及输出数值,两者内部均调用Xilinx官方提供的API函数。将实现细节隐藏最重要的步骤:将函数声明统一放置.h文件。
/*
* EMIO_ope.h
*
*/ #ifndef SRC_EMIO_OPE_H_
#define SRC_EMIO_OPE_H_ #define GPIO_DEVICE_ID XPAR_PS7_GPIO_0_DEVICE_ID int EMIO_init();
void writePin(u32 pinNum,u32 value);
u32 readPin(u32 pinNum); #endif /* SRC_EMIO_OPE_H_ */
此处总结下利用FPGA/SOC连接以太网从简单到难的设计方案是:协议栈芯片 --> LWIP开源库 --> 基于以太网MAC的网络协议逻辑设计--> 从上层网络协议到MAC全部用HDL描述。不同的方案适合不同的需求,能灵活在开发周期和性能 功耗等方面取舍,做到简单实用,应该是各个行业技术人员的所追求的终极目标。
ZYNQ EMIO使用及可重用封装的更多相关文章
- 利用ZYNQ SOC快速打开算法验证通路(2)——数据传输最简方案:网络调试助手+W5500协议栈芯片
在上一篇该系列博文中讲解了MATLAB待处理数据写入.bin二进制数据文件的过程,接下来需要将数据通过以太网发送到ZYNQ验证平台.之前了解过Xilinx公司面向DSP开发的System Genera ...
- 利用ZYNQ SOC快速打开算法验证通路(4)——AXI DMA使用解析及环路测试
一.AXI DMA介绍 本篇博文讲述AXI DMA的一些使用总结,硬件IP子系统搭建与SDK C代码封装参考米联客ZYNQ教程.若想让ZYNQ的PS与PL两部分高速数据传输,需要利用PS的HP(高性能 ...
- JAVA的三大特征 封装继承多态- 简单总结
简单总结一下 封装-即从很多类的抽取相同的代码 写在一个类里. 好处是 代码的重用,安全. 继承-减少代码的书写. 其好处也是 代码的重用. 多态- 把不同的子类对象都当作父类来看,可以屏蔽不同子类对 ...
- c++封装继承多态
面向对象的三个基本特征 封装.继承.多态.其中,封装可以隐藏实现细节,使得代码模块化:继承可以扩展已存在的代码模块(类):它们的目的都是为了——代码重用.而多态则是为了实现另一个目的——接口重用 封装 ...
- Vue之优化封装请求方法
Vue之优化封装请求方法 对于代码中的请求操作 1.接口请求可能需要重用 2.实际工作中,接口非常容易变动, 改起来很麻烦! 我们建议的做法是把所有的请求都封装成函数然后统一的>###组织到模块 ...
- javascript 设计模式-----模块模式
在一些大的项目中经常使用到模块,在这里,我们将了解一下什么是模块模式.模块模式最简单的方法大家一定会用过,如下所示: var a = { b : 1, c : 2 } 这样一个对象的直接量其实就已经是 ...
- JS 经典代码段总结 start from 2016-08-22
1.for(var i = 0, max = myArray.length; i < max ; i++){ //用myArrayy[i]来做点什么 } 用max存储myArray的长度,防止每 ...
- <深入理解JavaScript>学习笔记(3)_全面解析Module模式
简介 Module模式是JavaScript编程中一个非常通用的模式,一般情况下,大家都知道基本用法,本文尝试着给大家更多该模式的高级使用方式. 首先我们来看看Module模式的基本特征: 模块化,可 ...
- 驱动学习3.1:获取zynqled的物理地址
自己想要打印EMIO管脚的物理地址,在SDK提供的头文件中加入printf是无法打印的,基于此 我将需要打印地址的几个函数提取出来,放在main函数中,然后在里面加入printf打印这些用户管脚的地址 ...
随机推荐
- 微信小程序自动化测试实践
由于腾讯系QQ.微信等都是基于腾讯自研X5内核,不是google原生webview(其实就是进行了二次定制).实质上也是混合应用的一种,现在很多app产品也开始流行采用X5内核作为其内嵌web浏览服务 ...
- pycharm(Python编辑器)的激活
1.将“0.0.0.0 account.jetbrains.com”中的内容添加到hosts文件中,hosts路径为:C:\Windows\System32\drivers\etc mac用户的hos ...
- innerHTML,outerHTML,innerText,outerText
- innerHTML 设置或获取位于对象起始和结束标签内的 HTML - outerHTML 设置或获取对象及其内容的 HTML 形式 - innerText 设置或获取位于对象起始和结束标签内的文 ...
- 一个std::sort 自定义比较排序函数 crash的分析过程
两年未写总结博客,今天先来练练手,总结最近遇到的一个crash case. 注意:以下的分析都基于GCC4.4.6 一.解决crash 我们有一个复杂的排序,涉及到很多个因子,使用自定义排序函数的st ...
- 利用Visual Studio 2017的扩展开发(VSIX、ItemTemplate) 快速实现项目的半自动化搭建
目录 0.引言 1.什么是Visual Studio项目模板 2.IWizad接口 3.通过Visual Studio扩展开发实现领域驱动开发 3.1 使用VSIX+ProjectTemplate创建 ...
- dataframe的select传入不定参数
在提取 dataframe 里面的列时,需要传入不定参数,即 dataframe.select(args) .例如某个 dataframe 如下: 一般提取某列或者某几列的时候是这样子写的: data ...
- java基础(五)-----关键字static
在Java中并不存在全局变量的概念,但是我们可以通过static来实现一个“伪全局”的概念,在Java中static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,当然也可以修饰代码块. ...
- 并发编程(二)—— CountDownLatch、CyclicBarrier和Semaphore
本文将讲解CountDownLatch,CyclicBarrier和Semaphore这三个并发包里面的辅助类. CountDownLatch 正如每个Java文档所描述的那样,CountDownLa ...
- Python编写守护进程程序
Python编写守护进程程序思路 1. fork子进程,父进程退出通常,我们执行服务端程序的时候都会通过终端连接到服务器,成功连接后会加载shell环境,终端和shell都是进程,shell进程是终端 ...
- 编写基于Property-based的单元测试
编写基于Property-based的单元测试 作为一个开发者,你可能认为你的职责就是编写代码从而完成需求.我不敢苟同,开发者的工作是通过软件来解决现实需求,编写代码只是软件开发的其中一个方面,编写可 ...