閱讀1173 返回首頁    go 王者榮耀


ZED Board從入門到精通(三):從傳統ARM開發到PS開發的轉變

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官方例程的網址為https://www.xilinx.com/support/documentation/sw_manuals/xilinx14_2/ug873-zynq-ctt.pdf,步驟較多,讓人分不清到底是在做軟件設計還是硬件開發。

本節在參考了上麵例程的基礎上,進一步做了幾個小例子來說明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軟件(安裝完成後,一般在桌麵上會有快捷方式)。

單擊“Create New Project ”,新建工程,為了方便敘述,連續點6次“Next”,直到出現下圖:

 

左上框中選擇“board”,在下麵框中找到ZedBoard並選中,點Next,一直到Finish,結束。

在主麵板左側,點“Add Source”,添加一個嵌入式模塊(這就是ARM核),選擇如圖所示。

Next,點“Create Sub-Design”

隨便起個名吧,保留默認,OK,Finish。這個步驟主要功能是添加我們的ARM核心到萬用板上,但是還沒有連線。

 

這時PlanAhead會自動調用XPS,在XPS中,當有提問是否用BSB建立基本係統時,選“是”。OK,Next,出現下圖:

把原先右側的所有硬件都Remove掉,因為我們需要自己連線。點Finish。

看到了一個彩色的龐大係統,如下圖所示。

主窗口顯示的就是Zynq內部結構圖,主窗口上麵有四個標簽,“Zynq”表示圖形化顯示,“Bus Interface”表示總線連接,“Ports”表示芯片外部IO連接,“Address”表示Zynq係統的地址映射。主窗口下有3個標簽,有設計總結報告、係統組成顯示、圖形設計顯示。默認用係統組成顯示,另外兩種可以在設計完成後觀察。

 

我們點擊Zynq係統組成框圖中左上側綠色的"I/O Peripherals“框,彈出IO口外設配置選項,展開最下側的GPIO(點加號),勾上EMIO,並設置IO數目為8,如下圖所示:

 

 

 點關閉,然後從主窗口上麵標簽的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,如下圖所示:

這時生成了頂層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”,如圖所示

仍然點Create File,名稱隨便起,我們輸入system,最後確認,回到主窗口。這時看到Project Manager中添加了system.ucf

雙擊該文件,添加內容如下:

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;


如果對引腳的位置不太確定,可以參考我上傳的資源:https://download.csdn.net/detail/kkk584520/5901617  裏麵有ZEDBoard原理圖,其中有關LED的引腳如下圖所示:

 

為了防止生成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,確認:

經過一段時間的導出,進入了SDK開發界麵,點擊菜單File->New->Application Project,如下所示:

名稱隨便起一個吧,我們取為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 <stdio.h>
#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<<i;
    		delay_1s(1000);
    	}
    }
    cleanup_platform();

    return 0;
}


保存,程序會自動編譯。如果控製台輸出如下表示編譯無錯誤出現。

arm-xilinx-eabi-size led8.elf  |tee "led8.elf.size"
   text	   data	    bss	    dec	    hex	filename
  22304	   1096	  29780	  53180	   cfbc	led8.elf
'Finished building: led8.elf.size'
' '

19:38:31 Build Finished (took 7s.342ms)


 

我們的LED流水燈程序馬上就能跑了!別急,先做好運行準備。確保你的板子電源接好,MIO2~MIO6的短路帽都接地,USB-UART和USB-JTAG都連接到了電腦上,而且都已經安裝相應驅動程序。打開電源開關,先下載bit流文件到FPGA,點擊菜單Xilinx Tools->Launch Hardware Server,彈出一個黑框,不用管它(ISE14.2不需要這一步)。然後點擊菜單Xilinx Tools->Program FPGA,確保bit文件位置正確(你可以親自到相應目錄下找到這個文件,看更新時間戳是不是正確),點Program,等待FPGA編程結束。成功編程後,板子上的LD12藍燈會亮起。

 

接下來運行ARM端軟件,右鍵點擊工程瀏覽器中的led8,選擇Run As->Launch on Hardware。打開電腦上的超級終端(Win7沒有這個工具,我這裏用的是SecureCRT),連接好,等待程序加載完成後,就能看到實驗結果了,串口打印內容為:

板子上的8個LED則會呈現出流水燈的效果。

最終效果視頻地址為:https://v.youku.com/v_show/id_XNTk2ODg1ODU2.html

工程文件:https://download.csdn.net/detail/kkk584520/5961635

 

 總結:通過一個流水燈實驗,我們基本上熟悉了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開發的另一個難點就是邏輯開發。下一節我們介紹如何利用ISE工具開發PL邏輯。

 

最後更新:2017-04-03 16:48:57

  上一篇:go Error: Object INSTANCES_UTIL does not exist
  下一篇:go django版 helloworld