一文加深对zynq内部结构的理解

电子说

1.3w人已加入

描述

ARM已经在国内流行得一塌糊涂,各类教程、开发板(S3C2440,6410)层出不穷,归结下来,传统ARM开发包括以下几个步骤:

(1)硬件电路板设计(对于Zedboard,相当于设计逻辑电路,PL工程师负责);

(2)基本模块裸机代码测试(UART,DDR2,其他外设);

(3)移植操作系统(如Linux,uCLinux,uCOS等);

(4)编写相应操作系统的驱动程序(可从(2)中移植过来);

(5)编写应用程序(或移植已有的应用程序)、界面设计(Qt);

一个有ARM开发经验的工程师,接触Zynq时很容易陷入误区:到底哪一部分需要由逻辑完成,哪一部分由ARM完成?Zynq资料庞杂,怎样进行有效的学习?

从前面基本介绍我们知道,Zynq内部PS就是ARM工程师的战场,调试代码都是基于PS进行,如果出现问题(硬件问题、驱动问题、软件版本问题)如何定位是一项非常耗时的任务,尤其加入了逻辑设计之后,调试难度大大增加了。所以在一颗芯片中集成了ARM和FPGA虽然提高了性能,但也带来任务划分不明确,调试复杂等新问题。Zynq官方例程的网址为 ,步骤较多,让人分不清到底是在做软件设计还是硬件开发。

本节在参考了上面例程的基础上,进一步做了几个小例子来说明Zynq其实可以和普通ARM开发一样简单易学。将ARM设计与逻辑设计完全解耦,有利于我们加深对zynq内部结构的理解。

ARM工程师开发Zynq用到的软件环境主要有:

PlanAhead+XPS:建立硬件工程,相当于在一个万用板上自己搭建一个单片机最小系统,我们需要将单片机的IO口连接不同的外设(LED,按键,液晶屏,串口等);

SDK:建立软件工程,编写基本模块程序;建立Bootloader工程;

arm-xilinx-linux-gnueabi-gcc:交叉编译工具,编写基于Linux的应用程序和驱动程序;

几乎所有ARM工程师都是从单片机开始学习,而且第一个实验一般都是流水灯实验。ZedBoard上既然有一个ARM芯片,有8个LED,能不能用ARM点亮它们,并实现流水灯效果呢?我们来试试吧!

笔者安装软件为ISE14.5,其他版本操作类似。

(1)硬件电路板设计

首先,运行PlanAhead软件(安装完成后,一般在桌面上会有快捷方式)。

Zynq

单击“Create New Project ”,新建工程,为了方便叙述,连续点6次“Next”,直到出现下图:

Zynq

左上框中选择“board”,在下面框中找到ZedBoard并选中,点Next,一直到Finish,结束。

在主面板左侧,点“Add Source”,添加一个嵌入式模块(这就是ARM核),选择如图所示。

Zynq

Next,点“Create Sub-Design”

Zynq

随便起个名吧,保留默认,OK,Finish。这个步骤主要功能是添加我们的ARM核心到万用板上,但是还没有连线。

这时PlanAhead会自动调用XPS,在XPS中,当有提问是否用BSB建立基本系统时,选“是”。OK,Next,出现下图:

Zynq

把原先右侧的所有硬件都Remove掉,因为我们需要自己连线。点Finish。

看到了一个彩色的庞大系统,如下图所示。

Zynq

主窗口显示的就是Zynq内部结构图,主窗口上面有四个标签,“Zynq”表示图形化显示,“Bus Interface”表示总线连接,“Ports”表示芯片外部IO连接,“Address”表示Zynq系统的地址映射。主窗口下有3个标签,有设计总结报告、系统组成显示、图形设计显示。默认用系统组成显示,另外两种可以在设计完成后观察。

我们点击Zynq系统组成框图中左上侧绿色的“I/O Peripherals“框,弹出IO口外设配置选项,展开最下侧的GPIO(点加号),勾上EMIO,并设置IO数目为8,如下图所示:

Zynq

点关闭,然后从主窗口上面标签的Zynq标签切换到Ports标签,展开processing_system7_0(点加号),找到GPIO_0,将它设置为连接到外部引脚,如图所示。

什么是EMIO?什么是MIO?这是Zynq里面比较独特的特性。MIO就是ARM自己的手脚,完全由自己支配;而EMIO,则是FPGA的手脚,如果不做任何处理,ARM说什么对它们根本不起作用。Zynq有一种机制,可以通过布线,将一部分FPGA手脚连接到ARM上,接受ARM指挥,这样就可以方便地扩展ARM的IO口,使ARM也像FPGA那样,任意设置外部引脚,非常灵活。这个实验中,我们用了8个FPGA引脚接受ARM控制,上面操作已经设置完毕了。

接下来,需要检查硬件是否有错误。点击菜单Project-》Design Rule Check,如果在XPS Console窗口中输出如下内容,表示没有错误:

Running system level update procedures.。。

Running UPDATE Tcl procedures for OPTION SYSLEVEL_UPDATE_PROC.。。

Running system level DRCs.。。

Performing System level DRCs on properties.。。

Running DRC Tcl procedures for OPTION SYSLEVEL_DRC_PROC.。。

Done!

这时彻底关闭XPS,回到PlanAhead中。在Project Manager的Source窗口中,找到module_1.xmp,单击右键,选择Create Top HDL,如下图所示:

Zynq

这时生成了顶层HDL模块,名称为module_1_stub.v,打开这个文件,内容如下:

//-----------------------------------------------------------------------------

// module_1_stub.v

//-----------------------------------------------------------------------------

module module_1_stub

processing_system7_0_MIO,

processing_system7_0_PS_SRSTB,

processing_system7_0_PS_CLK,

processing_system7_0_PS_PORB,

processing_system7_0_DDR_Clk,

processing_system7_0_DDR_Clk_n,

processing_system7_0_DDR_CKE,

processing_system7_0_DDR_CS_n,

processing_system7_0_DDR_RAS_n,

processing_system7_0_DDR_CAS_n,

processing_system7_0_DDR_WEB_pin,

processing_system7_0_DDR_BankAddr,

processing_system7_0_DDR_Addr,

processing_system7_0_DDR_ODT,

processing_system7_0_DDR_DRSTB,

processing_system7_0_DDR_DQ,

processing_system7_0_DDR_DM,

processing_system7_0_DDR_DQS,

processing_system7_0_DDR_DQS_n,

processing_system7_0_DDR_VRN,

processing_system7_0_DDR_VRP,

processing_system7_0_GPIO_pin

);

inout [53:0] processing_system7_0_MIO;

input processing_system7_0_PS_SRSTB;

input processing_system7_0_PS_CLK;

input processing_system7_0_PS_PORB;

inout processing_system7_0_DDR_Clk;

inout processing_system7_0_DDR_Clk_n;

inout processing_system7_0_DDR_CKE;

inout processing_system7_0_DDR_CS_n;

inout processing_system7_0_DDR_RAS_n;

inout processing_system7_0_DDR_CAS_n;

output processing_system7_0_DDR_WEB_pin;

inout [2:0] processing_system7_0_DDR_BankAddr;

inout [14:0] processing_system7_0_DDR_Addr;

inout processing_system7_0_DDR_ODT;

inout processing_system7_0_DDR_DRSTB;

inout [31:0] processing_system7_0_DDR_DQ;

inout [3:0] processing_system7_0_DDR_DM;

inout [3:0] processing_system7_0_DDR_DQS;

inout [3:0] processing_system7_0_DDR_DQS_n;

inout processing_system7_0_DDR_VRN;

inout processing_system7_0_DDR_VRP;

inout [7:0] processing_system7_0_GPIO_pin;

(* BOX_TYPE = ”user_black_box“ *)

module_1

module_1_i (

.processing_system7_0_MIO ( processing_system7_0_MIO ),

.processing_system7_0_PS_SRSTB ( processing_system7_0_PS_SRSTB ),

.processing_system7_0_PS_CLK ( processing_system7_0_PS_CLK ),

.processing_system7_0_PS_PORB ( processing_system7_0_PS_PORB ),

.processing_system7_0_DDR_Clk ( processing_system7_0_DDR_Clk ),

.processing_system7_0_DDR_Clk_n ( processing_system7_0_DDR_Clk_n ),

.processing_system7_0_DDR_CKE ( processing_system7_0_DDR_CKE ),

.processing_system7_0_DDR_CS_n ( processing_system7_0_DDR_CS_n ),

.processing_system7_0_DDR_RAS_n ( processing_system7_0_DDR_RAS_n ),

.processing_system7_0_DDR_CAS_n ( processing_system7_0_DDR_CAS_n ),

.processing_system7_0_DDR_WEB_pin ( processing_system7_0_DDR_WEB_pin ),

.processing_system7_0_DDR_BankAddr ( processing_system7_0_DDR_BankAddr ),

.processing_system7_0_DDR_Addr ( processing_system7_0_DDR_Addr ),

.processing_system7_0_DDR_ODT ( processing_system7_0_DDR_ODT ),

.processing_system7_0_DDR_DRSTB ( processing_system7_0_DDR_DRSTB ),

.processing_system7_0_DDR_DQ ( processing_system7_0_DDR_DQ ),

.processing_system7_0_DDR_DM ( processing_system7_0_DDR_DM ),

.processing_system7_0_DDR_DQS ( processing_system7_0_DDR_DQS ),

.processing_system7_0_DDR_DQS_n ( processing_system7_0_DDR_DQS_n ),

.processing_system7_0_DDR_VRN ( processing_system7_0_DDR_VRN ),

.processing_system7_0_DDR_VRP ( processing_system7_0_DDR_VRP ),

.processing_system7_0_GPIO_pin ( processing_system7_0_GPIO_pin )

);

endmodule

可以看到,module_1_stub只是对我们用XPS创建的嵌入式模块module_1用verilog语言进行一层包装,相当于芯片制造业中将晶圆向外引线,做最后的邦定。我们后面会讲,在这一步也可以进行用户逻辑开发。

接着需要添加约束文件(UCF),还是在Project Manager中Add Source,这次类型选第一个“Constraints”,如图所示

Zynq

仍然点Create File,名称随便起,我们输入system,最后确认,回到主窗口。这时看到Project Manager中添加了system.ucf

Zynq

双击该文件,添加内容如下:

NET ”processing_system7_0_DDR_Addr[0]“ LOC = M4;

NET ”processing_system7_0_DDR_Addr[1]“ LOC = M5;

NET ”processing_system7_0_DDR_Addr[2]“ LOC = K4;

NET ”processing_system7_0_DDR_Addr[3]“ LOC = L4;

NET ”processing_system7_0_DDR_Addr[4]“ LOC = K6;

NET ”processing_system7_0_DDR_Addr[5]“ LOC = K5;

NET ”processing_system7_0_DDR_Addr[6]“ LOC = J7;

NET ”processing_system7_0_DDR_Addr[7]“ LOC = J6;

NET ”processing_system7_0_DDR_Addr[8]“ LOC = J5;

NET ”processing_system7_0_DDR_Addr[9]“ LOC = H5;

NET ”processing_system7_0_DDR_Addr[10]“ LOC = J3;

NET ”processing_system7_0_DDR_Addr[11]“ LOC = G5;

NET ”processing_system7_0_DDR_Addr[12]“ LOC = H4;

NET ”processing_system7_0_DDR_Addr[13]“ LOC = F4;

NET ”processing_system7_0_DDR_Addr[14]“ LOC = G4;

NET ”processing_system7_0_DDR_BankAddr[0]“ LOC = L7;

NET ”processing_system7_0_DDR_BankAddr[1]“ LOC = L6;

NET ”processing_system7_0_DDR_BankAddr[2]“ LOC = M6;

NET ”processing_system7_0_DDR_CAS_n“ LOC = P3;

NET ”processing_system7_0_DDR_CKE“ LOC = V3;

NET ”processing_system7_0_DDR_CS_n“ LOC = P6;

NET ”processing_system7_0_DDR_Clk“ LOC = N4;

NET ”processing_system7_0_DDR_Clk_n“ LOC = N5;

NET ”processing_system7_0_DDR_DM[0]“ LOC = B1;

NET ”processing_system7_0_DDR_DM[1]“ LOC = H3;

NET ”processing_system7_0_DDR_DM[2]“ LOC = P1;

NET ”processing_system7_0_DDR_DM[3]“ LOC = AA2;

NET ”processing_system7_0_DDR_DQ[0]“ LOC = D1;

NET ”processing_system7_0_DDR_DQ[1]“ LOC = C3;

NET ”processing_system7_0_DDR_DQ[2]“ LOC = B2;

NET ”processing_system7_0_DDR_DQ[3]“ LOC = D3;

NET ”processing_system7_0_DDR_DQ[4]“ LOC = E3;

NET ”processing_system7_0_DDR_DQ[5]“ LOC = E1;

NET ”processing_system7_0_DDR_DQ[6]“ LOC = F2;

NET ”processing_system7_0_DDR_DQ[7]“ LOC = F1;

NET ”processing_system7_0_DDR_DQ[8]“ LOC = G2;

NET ”processing_system7_0_DDR_DQ[9]“ LOC = G1;

NET ”processing_system7_0_DDR_DQ[10]“ LOC = L1;

NET ”processing_system7_0_DDR_DQ[11]“ LOC = L2;

NET ”processing_system7_0_DDR_DQ[12]“ LOC = L3;

NET ”processing_system7_0_DDR_DQ[13]“ LOC = K1;

NET ”processing_system7_0_DDR_DQ[14]“ LOC = J1;

NET ”processing_system7_0_DDR_DQ[15]“ LOC = K3;

NET ”processing_system7_0_DDR_DQ[16]“ LOC = M1;

NET ”processing_system7_0_DDR_DQ[17]“ LOC = T3;

NET ”processing_system7_0_DDR_DQ[18]“ LOC = N3;

NET ”processing_system7_0_DDR_DQ[19]“ LOC = T1;

NET ”processing_system7_0_DDR_DQ[20]“ LOC = R3;

NET ”processing_system7_0_DDR_DQ[21]“ LOC = T2;

NET ”processing_system7_0_DDR_DQ[22]“ LOC = M2;

NET ”processing_system7_0_DDR_DQ[23]“ LOC = R1;

NET ”processing_system7_0_DDR_DQ[24]“ LOC = AA3;

NET ”processing_system7_0_DDR_DQ[25]“ LOC = U1;

NET ”processing_system7_0_DDR_DQ[26]“ LOC = AA1;

NET ”processing_system7_0_DDR_DQ[27]“ LOC = U2;

NET ”processing_system7_0_DDR_DQ[28]“ LOC = W1;

NET ”processing_system7_0_DDR_DQ[29]“ LOC = Y3;

NET ”processing_system7_0_DDR_DQ[30]“ LOC = W3;

NET ”processing_system7_0_DDR_DQ[31]“ LOC = Y1;

NET ”processing_system7_0_DDR_DQS[0]“ LOC = C2;

NET ”processing_system7_0_DDR_DQS[1]“ LOC = H2;

NET ”processing_system7_0_DDR_DQS[2]“ LOC = N2;

NET ”processing_system7_0_DDR_DQS[3]“ LOC = V2;

NET ”processing_system7_0_DDR_DQS_n[0]“ LOC = D2;

NET ”processing_system7_0_DDR_DQS_n[1]“ LOC = J2;

NET ”processing_system7_0_DDR_DQS_n[2]“ LOC = P2;

NET ”processing_system7_0_DDR_DQS_n[3]“ LOC = W2;

NET ”processing_system7_0_DDR_DRSTB“ LOC = F3;

NET ”processing_system7_0_DDR_ODT“ LOC = P5;

NET ”processing_system7_0_DDR_RAS_n“ LOC = R5;

NET ”processing_system7_0_DDR_VRN“ LOC = M7;

NET ”processing_system7_0_DDR_VRP“ LOC = N7;

NET ”processing_system7_0_DDR_WEB_pin“ LOC = R4;

NET ”processing_system7_0_MIO[0]“ LOC = G6;

NET ”processing_system7_0_MIO[1]“ LOC = A1;

NET ”processing_system7_0_MIO[2]“ LOC = A2;

NET ”processing_system7_0_MIO[3]“ LOC = F6;

NET ”processing_system7_0_MIO[4]“ LOC = E4;

NET ”processing_system7_0_MIO[5]“ LOC = A3;

NET ”processing_system7_0_MIO[6]“ LOC = A4;

NET ”processing_system7_0_MIO[7]“ LOC = D5;

NET ”processing_system7_0_MIO[8]“ LOC = E5;

NET ”processing_system7_0_MIO[9]“ LOC = C4;

NET ”processing_system7_0_MIO[10]“ LOC = G7;

NET ”processing_system7_0_MIO[11]“ LOC = B4;

NET ”processing_system7_0_MIO[12]“ LOC = C5;

NET ”processing_system7_0_MIO[13]“ LOC = A6;

NET ”processing_system7_0_MIO[14]“ LOC = B6;

NET ”processing_system7_0_MIO[15]“ LOC = E6;

NET ”processing_system7_0_MIO[16]“ LOC = D6;

NET ”processing_system7_0_MIO[17]“ LOC = E9;

NET ”processing_system7_0_MIO[18]“ LOC = A7;

NET ”processing_system7_0_MIO[19]“ LOC = E10;

NET ”processing_system7_0_MIO[20]“ LOC = A8;

NET ”processing_system7_0_MIO[21]“ LOC = F11;

NET ”processing_system7_0_MIO[22]“ LOC = A14;

NET ”processing_system7_0_MIO[23]“ LOC = E11;

NET ”processing_system7_0_MIO[24]“ LOC = B7;

NET ”processing_system7_0_MIO[25]“ LOC = F12;

NET ”processing_system7_0_MIO[26]“ LOC = A13;

NET ”processing_system7_0_MIO[27]“ LOC = D7;

NET ”processing_system7_0_MIO[28]“ LOC = A12;

NET ”processing_system7_0_MIO[29]“ LOC = E8;

NET ”processing_system7_0_MIO[30]“ LOC = A11;

NET ”processing_system7_0_MIO[31]“ LOC = F9;

NET ”processing_system7_0_MIO[32]“ LOC = C7;

NET ”processing_system7_0_MIO[33]“ LOC = G13;

NET ”processing_system7_0_MIO[34]“ LOC = B12;

NET ”processing_system7_0_MIO[35]“ LOC = F14;

NET ”processing_system7_0_MIO[36]“ LOC = A9;

NET ”processing_system7_0_MIO[37]“ LOC = B14;

NET ”processing_system7_0_MIO[38]“ LOC = F13;

NET ”processing_system7_0_MIO[39]“ LOC = C13;

NET ”processing_system7_0_MIO[40]“ LOC = E14;

NET ”processing_system7_0_MIO[41]“ LOC = C8;

NET ”processing_system7_0_MIO[42]“ LOC = D8;

NET ”processing_system7_0_MIO[43]“ LOC = B11;

NET ”processing_system7_0_MIO[44]“ LOC = E13;

NET ”processing_system7_0_MIO[45]“ LOC = B9;

NET ”processing_system7_0_MIO[46]“ LOC = D12;

NET ”processing_system7_0_MIO[47]“ LOC = B10;

NET ”processing_system7_0_MIO[48]“ LOC = D11;

NET ”processing_system7_0_MIO[49]“ LOC = C14;

NET ”processing_system7_0_MIO[50]“ LOC = D13;

NET ”processing_system7_0_MIO[51]“ LOC = C10;

NET ”processing_system7_0_MIO[52]“ LOC = D10;

NET ”processing_system7_0_MIO[53]“ LOC = C12;

NET ”processing_system7_0_GPIO_pin[0]“ LOC = T22;

NET ”processing_system7_0_GPIO_pin[1]“ LOC = T21;

NET ”processing_system7_0_GPIO_pin[2]“ LOC = U22;

NET ”processing_system7_0_GPIO_pin[3]“ LOC = U21;

NET ”processing_system7_0_GPIO_pin[4]“ LOC = V22;

NET ”processing_system7_0_GPIO_pin[5]“ LOC = W22;

NET ”processing_system7_0_GPIO_pin[6]“ LOC = U19;

NET ”processing_system7_0_GPIO_pin[7]“ LOC = U14;

NET ”processing_system7_0_GPIO_pin[7]“ IOSTANDARD = LVCMOS33;

NET ”processing_system7_0_GPIO_pin[6]“ IOSTANDARD = LVCMOS33;

NET ”processing_system7_0_GPIO_pin[5]“ IOSTANDARD = LVCMOS33;

NET ”processing_system7_0_GPIO_pin[4]“ IOSTANDARD = LVCMOS33;

NET ”processing_system7_0_GPIO_pin[3]“ IOSTANDARD = LVCMOS33;

NET ”processing_system7_0_GPIO_pin[2]“ IOSTANDARD = LVCMOS33;

NET ”processing_system7_0_GPIO_pin[1]“ IOSTANDARD = LVCMOS33;

NET ”processing_system7_0_GPIO_pin[0]“ IOSTANDARD = LVCMOS33;

如果对引脚的位置不太确定,可以参考我上传的资源: 里面有ZEDBoard原理图,其中有关LED的引脚如下图所示:

Zynq

为了防止生成FPGA比特文件时报错,需要设置一下属性:

点菜单Flow-》Bitstream Settings,设置More Options的值为-g UnconstrainedPins:Allow,点OK。

做完上面的内容,接着点击菜单Flow-》Generate Bitstream。等大约5分钟(PC配置不同,时间有长有短),直到生成bitstream成功。这样就把FPGA逻辑设计部分工作做完了。

其实实际项目中,上述工作一般都是由逻辑开发工程师完成的,我们这个例子讲得如此详细是为了让ARM工程师对硬件有个较为深入的了解,这样后期调试时会更加得心应手。况且Xilinx把所有软件都集成在了PlanAhead中,ARM工程师不再像以前那样,直接用RealView MDK写代码,而是必须基于刚刚搭建的硬件环境用Xilinx的SDK开发工具完成软件设计。

下面将前面的硬件工程导出到SDK。

点击菜单File-》Export-》Export Hardware for SDK,弹出对话框,勾上Launch SDK,确认:

Zynq

经过一段时间的导出,进入了SDK开发界面,点击菜单File-》New-》Application Project,如下所示:

Zynq

名称随便起一个吧,我们取为led8,下一步,模板选择Hello World,这也是最基础的模板,后面我们大部分应用程序都基于这个模板。

打开helloworld.c,代码修改为:

/*

* Copyright (c) 2009 Xilinx, Inc. All rights reserved.

*

* Xilinx, Inc.

* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION ”AS IS“ AS A

* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS

* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR

* STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION

* IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE

* FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.

* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO

* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO

* ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE

* FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY

* AND FITNESS FOR A PARTICULAR PURPOSE.

*

*/

/*

* helloworld.c: simple test application

*/

#include

#include ”platform.h“

#define MIO_BASE 0xE000A000

#define DATA1_RO 0x64

#define DATA2 0x48

#define DATA2_RO 0x68

#define DIRM_2 0x284

#define OEN_2 0x288

void print(char *str);

void delay_1s(int i)

{

int j;

while(i--)

{

j=10000;

while(j--)

{

__asm(”NOP“);

}

}

}

int main()

{

int i;

init_platform();

*((volatile int*)(MIO_BASE+OEN_2)) = 0xff;

*((volatile int*)(MIO_BASE+DIRM_2)) = 0xff;

print(”Hello world!\r\nThe Leds are flowing.。。\r\n“);

while(1)

{

for(i = 0;i 《 8; i++)

{

*((volatile int*)(MIO_BASE+DATA2)) = 0x01

接下来运行ARM端软件,右键点击工程浏览器中的led8,选择Run As-》Launch on Hardware。打开电脑上的超级终端(Win7没有这个工具,我这里用的是SecureCRT),连接好,等待程序加载完成后,就能看到实验结果了,串口打印内容为:

Zynq

板子上的8个LED则会呈现出流水灯的效果。

最终效果视频地址为:

工程文件:

总结:通过一个流水灯实验,我们基本上熟悉了Zynq开发需要的几个工具软件。步骤虽然很多,但有了一个清晰的方向,就不会迷失在各个软件的繁琐操作中。本博文不希望成为一个详细的傻瓜级教程(由于是第一个实验,步骤比较详细,后面的实验会非常简洁,所以不熟悉软件操作的童鞋要多加练习),也不想成为官方文档的简单堆砌和翻译,而是希望成为一个指路牌,告诉你在茫茫软件中何去何从。

ARM工程师关注的细节,应该是各类硬件寄存器,如GPIO,PLL,Timer,WDT,UART,SPI等等,这些寄存器可以从官方文档Zynq-7000-TRM中得到。经常查阅TRM是开发驱动、硬件接口必不可少的环节,如果需要移植操作系统,还需要查看ARM内核相应文档,如cortex_a9_mpcore_r4p1_trm,cortex_a9_neon_mpe_r4p1_trm等。一般来说,应用工程师需要熟悉相应的API,操作系统驱动工程师需要熟悉内核调用,裸机驱动工程师需要熟悉硬件协议。在一个项目中,需要所有工程师分工协作,这样才能高效地完成设计。

ARM工程师很多软件模块可以参考官方设计,在{ISE安装路径}\14.5\ISE_DS\EDK\sw\XilinxProcessorIPLib\drivers中有很多外设操作的例程,不需要从头开发。

在ARM之外,Zynq开发的另一个难点就是逻辑开发。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分