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