由于Xilinx已經(jīng)為我們做了大部分的鋪墊工作,因此裸奔控制外設(shè)這一步就顯得十分簡(jiǎn)單了,如果不用Linux和圖形界面顯示,大概我的作品早早的就完成了吧。上一次我們已經(jīng)成功生成了BitStream文件,下面繼續(xù)上次的操作,打開(kāi)PlanAhead工程,選擇Export Hardware for SDK,如下圖:
在彈出的窗口中選上Launch SDK,OK以后進(jìn)入SDK界面。
?SDK界面下編寫(xiě)裸奔軟件的方法在ZedBoard_CTT文檔中已經(jīng)悉數(shù)介紹了,這里和官方文檔中的唯一差異就是需要添加控制AXI總線(xiàn)設(shè)備的底層代碼。首先新建一個(gè)C工程。
工程模板選擇Hello World,點(diǎn)擊Next。
?BPS部分默認(rèn)即可,點(diǎn)Finish完成。
?之后添加我們自己建立的my_gpio外設(shè)的控制代碼。不會(huì)控制AXI總線(xiàn)設(shè)備?沒(méi)關(guān)系,由于之前在創(chuàng)建外設(shè)的時(shí)候勾選了生成driver的配置項(xiàng),Xilinx已經(jīng)自動(dòng)生成了裸奔的控制代碼。代碼位于XPS工程的文件目錄下,兔子這里的路徑是“Hello_ZedHello_Zed.srcssources_1edkmodule_1driversmy_gpio_v1_00_asrc”,將里面的my_gpio.h直接拖進(jìn)SDK左邊的hello_world工程里,并在helloworld.c文件里添加對(duì)my_gpio.h的引用:#include?"my_gpio.h"?有的童鞋可能在編譯的時(shí)候會(huì)遇到問(wèn)題,提示找不到xbasic_types.h文件。同時(shí)在my_gpio.h文件的左下角會(huì)顯示一個(gè)小叉。
?出現(xiàn)此問(wèn)題時(shí),可以手動(dòng)添加這個(gè)頭文件的路徑,一般就在Xilinx ISE的安裝目錄中,我的電腦上就是:#include"D:Xilinx14.2ISE_DSEDKswXilinxProcessorIPLibdriverscommon_v1_00_asrcxbasic_types.h"?如果這個(gè)時(shí)候編譯工程不出問(wèn)題,就可以開(kāi)始寫(xiě)測(cè)試代碼了。在my_gpio.h中定義了一些控制AXI總線(xiàn)設(shè)備寄存器的函數(shù),如mReadSlaveReg和mWriteSlaveReg。通過(guò)這些函數(shù)就能夠讀寫(xiě)寄存器內(nèi)容了。需要注意的是,想要控制外設(shè)還需要知道它的設(shè)備物理地址,該地址可以在工程中的XML文件中查看,比如在這里my_gpio設(shè)備的地址就是0x75C00000。
?這里附上一個(gè)簡(jiǎn)單的測(cè)試?yán)?,可以測(cè)試我們的外設(shè)是否符合設(shè)計(jì)要求。其功能為:讀取兩個(gè)寄存器值,根據(jù)終端輸入修改寄存器,最后再次讀出驗(yàn)證修改效果。代碼如下:#include#include?"platform.h"#include?"my_gpio.h"?#define?MY_GPIO_ADDR??? 0x75C00000?//設(shè)備物理地址int?reg0, reg1;?int?main(){??? init_platform();????//讀取寄存器初始值????printf("======= My_GPIO Test ======= ");????printf("Reading my_gpio registers... ");??? reg0 = MY_GPIO_mReadSlaveReg0(MY_GPIO_ADDR, 0);??? reg1 = MY_GPIO_mReadSlaveReg1(MY_GPIO_ADDR, 0);????printf("Reg0=0x%x, Reg1=0x%x ", reg0, reg1);????//向寄存器寫(xiě)入數(shù)據(jù)????printf("Input Reg0. ");????scanf("%d", ®0);????printf("Input Reg1. ");????scanf("%d", ®1);????printf("Writing to my_gpio registers... ");??? MY_GPIO_mWriteSlaveReg0(MY_GPIO_ADDR, 0, reg0);??? MY_GPIO_mWriteSlaveReg1(MY_GPIO_ADDR, 0, reg1);????//讀取寄存器驗(yàn)證修改結(jié)果????printf("Read my_gpio registers... ");??? reg0 = MY_GPIO_mReadSlaveReg0(MY_GPIO_ADDR, 0);??? reg1 = MY_GPIO_mReadSlaveReg1(MY_GPIO_ADDR, 0);????printf("Reg0=0x%x, Reg1=0x%x ", reg0, reg1);???? cleanup_platform();????return?0;}??下面讓我們將代碼寫(xiě)入Zynq,運(yùn)行一下看看吧。首先編譯一下工程,完成后選擇Program FPGA,為PL部分載入邏輯配置。
?因?yàn)閺腜lanAhead導(dǎo)出到SDK時(shí),已經(jīng)選擇了包含BitStream文件,因此這一欄已經(jīng)自動(dòng)完成了,未自動(dòng)添加路徑的可以根據(jù)圖中的地址手動(dòng)添加。點(diǎn)擊Program,開(kāi)始下載配置數(shù)據(jù)。
?稍等片刻,Program完成后,選擇Run Configurations配置運(yùn)行選項(xiàng)。
?在彈出的窗口中,右擊Xilinx C/C++ Elf,選擇New,新建一個(gè)Debug項(xiàng)。
?選擇新建的hello_world_0 Debug項(xiàng),點(diǎn)擊Run就可以運(yùn)行代碼了。這里C/C++ Application一欄已經(jīng)自動(dòng)填充了elf文件的路徑,如果沒(méi)有填充(可能是工程還未編譯完成),就從Debug文件夾中手動(dòng)添加。Run Configurations中的選項(xiàng)都采用了默認(rèn)配置,這些選項(xiàng)的作用和設(shè)置方法請(qǐng)參見(jiàn)ZedBoard_CTT文檔,此處不再贅述。
?代碼運(yùn)行后,打開(kāi)串口終端軟件(兔子用的是SecureCRT),在115200bps波特率下,串口開(kāi)始輸出信息。首先會(huì)顯示兩個(gè)寄存器中的默認(rèn)值(皆為0x0),然后將SW7、SW5、SW3、SW1向上撥,設(shè)為高電平,其他保持低電平。再通過(guò)鍵盤(pán)輸入兩次85和回車(chē),即向兩個(gè)寄存器中都寫(xiě)入0x55。由于寄存器0為只讀寄存器,其內(nèi)容只根據(jù)Switch狀態(tài)改變,因此reg0結(jié)果為0xAA,即我們對(duì)開(kāi)關(guān)設(shè)置的數(shù)值,同時(shí)LED0、LED2、LED4、LED6會(huì)被點(diǎn)亮。代碼正常工作啦,串口輸出如圖:
?上實(shí)測(cè)照片:
?確實(shí)很簡(jiǎn)單吧,Xilinx看來(lái)在方便用戶(hù)這點(diǎn)上還做的不錯(cuò)。在驗(yàn)證完邏輯的正確性后,就要開(kāi)始為L(zhǎng)inux控制外設(shè)做準(zhǔn)備了, 請(qǐng)見(jiàn)下回。來(lái)源:電子懶兔的博客
評(píng)論
查看更多