ARM已經(jīng)在國(guó)內(nèi)流行得一塌糊涂,各類教程、開發(fā)板(S3C2440,6410)層出不窮,歸結(jié)下來,傳統(tǒng)ARM開發(fā)包括以下幾個(gè)步驟:
(1)硬件電路板設(shè)計(jì)(對(duì)于Zedboard,相當(dāng)于設(shè)計(jì)邏輯電路,PL工程師負(fù)責(zé));
(2)基本模塊裸機(jī)代碼測(cè)試(UART,DDR2,其他外設(shè));
(3)移植操作系統(tǒng)(如Linux,uCLinux,uCOS等);
(4)編寫相應(yīng)操作系統(tǒng)的驅(qū)動(dòng)程序(可從(2)中移植過來);
(5)編寫應(yīng)用程序(或移植已有的應(yīng)用程序)、界面設(shè)計(jì)(Qt);
一個(gè)有ARM開發(fā)經(jīng)驗(yàn)的工程師,接觸Zynq時(shí)很容易陷入誤區(qū):到底哪一部分需要由邏輯完成,哪一部分由ARM完成?Zynq資料龐雜,怎樣進(jìn)行有效的學(xué)習(xí)?
從前面基本介紹我們知道,Zynq內(nèi)部PS就是ARM工程師的戰(zhàn)場(chǎng),調(diào)試代碼都是基于PS進(jìn)行,如果出現(xiàn)問題(硬件問題、驅(qū)動(dòng)問題、軟件版本問題)如何定位是一項(xiàng)非常耗時(shí)的任務(wù),尤其加入了邏輯設(shè)計(jì)之后,調(diào)試難度大大增加了。所以在一顆芯片中集成了ARM和FPGA雖然提高了性能,但也帶來任務(wù)劃分不明確,調(diào)試復(fù)雜等新問題。Zynq官方例程的網(wǎng)址為 ,步驟較多,讓人分不清到底是在做軟件設(shè)計(jì)還是硬件開發(fā)。
本節(jié)在參考了上面例程的基礎(chǔ)上,進(jìn)一步做了幾個(gè)小例子來說明Zynq其實(shí)可以和普通ARM開發(fā)一樣簡(jiǎn)單易學(xué)。將ARM設(shè)計(jì)與邏輯設(shè)計(jì)完全解耦,有利于我們加深對(duì)zynq內(nèi)部結(jié)構(gòu)的理解。
ARM工程師開發(fā)Zynq用到的軟件環(huán)境主要有:
PlanAhead+XPS:建立硬件工程,相當(dāng)于在一個(gè)萬用板上自己搭建一個(gè)單片機(jī)最小系統(tǒng),我們需要將單片機(jī)的IO口連接不同的外設(shè)(LED,按鍵,液晶屏,串口等);
SDK:建立軟件工程,編寫基本模塊程序;建立Bootloader工程;
arm-xilinx-linux-gnueabi-gcc:交叉編譯工具,編寫基于Linux的應(yīng)用程序和驅(qū)動(dòng)程序;
幾乎所有ARM工程師都是從單片機(jī)開始學(xué)習(xí),而且第一個(gè)實(shí)驗(yàn)一般都是流水燈實(shí)驗(yàn)。ZedBoard上既然有一個(gè)ARM芯片,有8個(gè)LED,能不能用ARM點(diǎn)亮它們,并實(shí)現(xiàn)流水燈效果呢?我們來試試吧!
筆者安裝軟件為ISE14.5,其他版本操作類似。
(1)硬件電路板設(shè)計(jì)
首先,運(yùn)行PlanAhead軟件(安裝完成后,一般在桌面上會(huì)有快捷方式)。
單擊“Create New Project ”,新建工程,為了方便敘述,連續(xù)點(diǎn)6次“Next”,直到出現(xiàn)下圖:
左上框中選擇“board”,在下面框中找到ZedBoard并選中,點(diǎn)Next,一直到Finish,結(jié)束。
在主面板左側(cè),點(diǎn)“Add Source”,添加一個(gè)嵌入式模塊(這就是ARM核),選擇如圖所示。
Next,點(diǎn)“Create Sub-Design”
隨便起個(gè)名吧,保留默認(rèn),OK,F(xiàn)inish。這個(gè)步驟主要功能是添加我們的ARM核心到萬用板上,但是還沒有連線。
這時(shí)PlanAhead會(huì)自動(dòng)調(diào)用XPS,在XPS中,當(dāng)有提問是否用BSB建立基本系統(tǒng)時(shí),選“是”。OK,Next,出現(xiàn)下圖:
把原先右側(cè)的所有硬件都Remove掉,因?yàn)槲覀冃枰约哼B線。點(diǎn)Finish。
看到了一個(gè)彩色的龐大系統(tǒng),如下圖所示。
主窗口顯示的就是Zynq內(nèi)部結(jié)構(gòu)圖,主窗口上面有四個(gè)標(biāo)簽,“Zynq”表示圖形化顯示,“Bus Interface”表示總線連接,“Ports”表示芯片外部IO連接,“Address”表示Zynq系統(tǒng)的地址映射。主窗口下有3個(gè)標(biāo)簽,有設(shè)計(jì)總結(jié)報(bào)告、系統(tǒng)組成顯示、圖形設(shè)計(jì)顯示。默認(rèn)用系統(tǒng)組成顯示,另外兩種可以在設(shè)計(jì)完成后觀察。
我們點(diǎn)擊Zynq系統(tǒng)組成框圖中左上側(cè)綠色的“I/O Peripherals“框,彈出IO口外設(shè)配置選項(xiàng),展開最下側(cè)的GPIO(點(diǎn)加號(hào)),勾上EMIO,并設(shè)置IO數(shù)目為8,如下圖所示:
點(diǎn)關(guān)閉,然后從主窗口上面標(biāo)簽的Zynq標(biāo)簽切換到Ports標(biāo)簽,展開processing_system7_0(點(diǎn)加號(hào)),找到GPIO_0,將它設(shè)置為連接到外部引腳,如圖所示。
什么是EMIO?什么是MIO?這是Zynq里面比較獨(dú)特的特性。MIO就是ARM自己的手腳,完全由自己支配;而EMIO,則是FPGA的手腳,如果不做任何處理,ARM說什么對(duì)它們根本不起作用。Zynq有一種機(jī)制,可以通過布線,將一部分FPGA手腳連接到ARM上,接受ARM指揮,這樣就可以方便地?cái)U(kuò)展ARM的IO口,使ARM也像FPGA那樣,任意設(shè)置外部引腳,非常靈活。這個(gè)實(shí)驗(yàn)中,我們用了8個(gè)FPGA引腳接受ARM控制,上面操作已經(jīng)設(shè)置完畢了。
接下來,需要檢查硬件是否有錯(cuò)誤。點(diǎn)擊菜單Project-》Design Rule Check,如果在XPS Console窗口中輸出如下內(nèi)容,表示沒有錯(cuò)誤:
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!
這時(shí)徹底關(guān)閉XPS,回到PlanAhead中。在Project Manager的Source窗口中,找到module_1.xmp,單擊右鍵,選擇Create Top HDL,如下圖所示:
這時(shí)生成了頂層HDL模塊,名稱為module_1_stub.v,打開這個(gè)文件,內(nèi)容如下:
//-----------------------------------------------------------------------------
// 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只是對(duì)我們用XPS創(chuàng)建的嵌入式模塊module_1用verilog語言進(jìn)行一層包裝,相當(dāng)于芯片制造業(yè)中將晶圓向外引線,做最后的邦定。我們后面會(huì)講,在這一步也可以進(jìn)行用戶邏輯開發(fā)。
接著需要添加約束文件(UCF),還是在Project Manager中Add Source,這次類型選第一個(gè)“Constraints”,如圖所示
仍然點(diǎn)Create File,名稱隨便起,我們輸入system,最后確認(rèn),回到主窗口。這時(shí)看到Project Manager中添加了system.ucf
雙擊該文件,添加內(nèi)容如下:
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;
如果對(duì)引腳的位置不太確定,可以參考我上傳的資源: 里面有ZEDBoard原理圖,其中有關(guān)LED的引腳如下圖所示:
為了防止生成FPGA比特文件時(shí)報(bào)錯(cuò),需要設(shè)置一下屬性:
點(diǎn)菜單Flow-》Bitstream Settings,設(shè)置More Options的值為-g UnconstrainedPins:Allow,點(diǎn)OK。
做完上面的內(nèi)容,接著點(diǎn)擊菜單Flow-》Generate Bitstream。等大約5分鐘(PC配置不同,時(shí)間有長(zhǎng)有短),直到生成bitstream成功。這樣就把FPGA邏輯設(shè)計(jì)部分工作做完了。
其實(shí)實(shí)際項(xiàng)目中,上述工作一般都是由邏輯開發(fā)工程師完成的,我們這個(gè)例子講得如此詳細(xì)是為了讓ARM工程師對(duì)硬件有個(gè)較為深入的了解,這樣后期調(diào)試時(shí)會(huì)更加得心應(yīng)手。況且Xilinx把所有軟件都集成在了PlanAhead中,ARM工程師不再像以前那樣,直接用RealView MDK寫代碼,而是必須基于剛剛搭建的硬件環(huán)境用Xilinx的SDK開發(fā)工具完成軟件設(shè)計(jì)。
下面將前面的硬件工程導(dǎo)出到SDK。
點(diǎn)擊菜單File-》Export-》Export Hardware for SDK,彈出對(duì)話框,勾上Launch SDK,確認(rèn):
經(jīng)過一段時(shí)間的導(dǎo)出,進(jìn)入了SDK開發(fā)界面,點(diǎn)擊菜單File-》New-》Application Project,如下所示:
名稱隨便起一個(gè)吧,我們?nèi)閘ed8,下一步,模板選擇Hello World,這也是最基礎(chǔ)的模板,后面我們大部分應(yīng)用程序都基于這個(gè)模板。
打開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
接下來運(yùn)行ARM端軟件,右鍵點(diǎn)擊工程瀏覽器中的led8,選擇Run As-》Launch on Hardware。打開電腦上的超級(jí)終端(Win7沒有這個(gè)工具,我這里用的是SecureCRT),連接好,等待程序加載完成后,就能看到實(shí)驗(yàn)結(jié)果了,串口打印內(nèi)容為:
板子上的8個(gè)LED則會(huì)呈現(xiàn)出流水燈的效果。
最終效果視頻地址為:
工程文件:
總結(jié):通過一個(gè)流水燈實(shí)驗(yàn),我們基本上熟悉了Zynq開發(fā)需要的幾個(gè)工具軟件。步驟雖然很多,但有了一個(gè)清晰的方向,就不會(huì)迷失在各個(gè)軟件的繁瑣操作中。本博文不希望成為一個(gè)詳細(xì)的傻瓜級(jí)教程(由于是第一個(gè)實(shí)驗(yàn),步驟比較詳細(xì),后面的實(shí)驗(yàn)會(huì)非常簡(jiǎn)潔,所以不熟悉軟件操作的童鞋要多加練習(xí)),也不想成為官方文檔的簡(jiǎn)單堆砌和翻譯,而是希望成為一個(gè)指路牌,告訴你在茫茫軟件中何去何從。
ARM工程師關(guān)注的細(xì)節(jié),應(yīng)該是各類硬件寄存器,如GPIO,PLL,Timer,WDT,UART,SPI等等,這些寄存器可以從官方文檔Zynq-7000-TRM中得到。經(jīng)常查閱TRM是開發(fā)驅(qū)動(dòng)、硬件接口必不可少的環(huán)節(jié),如果需要移植操作系統(tǒng),還需要查看ARM內(nèi)核相應(yīng)文檔,如cortex_a9_mpcore_r4p1_trm,cortex_a9_neon_mpe_r4p1_trm等。一般來說,應(yīng)用工程師需要熟悉相應(yīng)的API,操作系統(tǒng)驅(qū)動(dòng)工程師需要熟悉內(nèi)核調(diào)用,裸機(jī)驅(qū)動(dòng)工程師需要熟悉硬件協(xié)議。在一個(gè)項(xiàng)目中,需要所有工程師分工協(xié)作,這樣才能高效地完成設(shè)計(jì)。
ARM工程師很多軟件模塊可以參考官方設(shè)計(jì),在{ISE安裝路徑}\14.5\ISE_DS\EDK\sw\XilinxProcessorIPLib\drivers中有很多外設(shè)操作的例程,不需要從頭開發(fā)。
在ARM之外,Zynq開發(fā)的另一個(gè)難點(diǎn)就是邏輯開發(fā)。
-
ARM
+關(guān)注
關(guān)注
134文章
9325瀏覽量
375622 -
Zynq
+關(guān)注
關(guān)注
10文章
614瀏覽量
48081
發(fā)布評(píng)論請(qǐng)先 登錄
芯片封裝內(nèi)部結(jié)構(gòu)
如何理解單片機(jī)內(nèi)部結(jié)構(gòu)原理
按鍵的內(nèi)部結(jié)構(gòu)與矩陣鍵盤掃描原理解析
深度剖析汽車內(nèi)部結(jié)構(gòu)和原理

評(píng)論