寫在前面
ZYNQ固化時,正常情況下都需要DDR參與,但是有時硬件設計時,可能將DDR去掉或設計出錯,這將導致ZYNQ無法正常固化,之前有寫過一個使用靜態鏈接庫進行無DDR固化的文章,當時那個是壓縮了FSBL的相關代碼只保留FLASH模式下的功能,對于其他模式可能無法正常使用,本文將無DDR固化的情況進一步進行介紹,講解如何修改FSBL實現ZYNQ的程序固化,給出一個demo進行演示測試。
適用范圍
不論是之前提到的靜態鏈接庫的版本還是本文版本(暫且叫做運行在OCM版本)。都只適合PS端的輕量級代碼,PL端無特殊要求,但是PL PS交互部分如果需要太多驅動可能也會超出片上RAM的空間。本工程根本思想就是將fsbl分配到較大的ocm0上,其余應用工程分配到ocm1上。
建立工程
建立一個Block design,添加zynq核,然后勾選,FLASH和UART部分。
ZYNQ配置界面
這里為了驗證PL端功能正常啟動,添加了一個邏輯常數用于驅動LED燈。
連接界面
創建HDL頂層,生成output products,因為涉及到PL端部分,所以需要綜合導出生成bitstream,不要忘記加管腳約束。
操作步驟
當運行生成bitstream后,導出硬件,并且包含bit流文件。
準備好硬件平臺后就可以進行SDK的FSBL代碼的修改了。
SDK代碼修改
新建應用工程建一個helloworld工程,打開lscript.ld文件將helloworld的代碼段映射區對應到ps7_ram_1,保存編譯。
helloworld工程的lscript.ld文件
新建應用工程建一個fsbl工程,打開lscript.ld文件將helloworld的代碼段映射區對應到ps7_ram_0,保存編譯。
fsbl工程的lscript.ld文件
打開fsbl代碼的fsbl_debug.h文件,增加FSBL_DEBUG_INFO的宏定義方便進行查看fsbl的調試信息。
增加FSBL_DEBUG_INFO
打開main.c文件,找到main函數,定位到296行附近,在這里可以看到因為缺少ddr的部分,該部分代碼將不會正常執行,將會跳轉到下面的代碼中。
定位代碼
代碼以下兩行代碼執行后FSBL 狀態打印輸出0XA008,在fsbl.h文件中對應DDR missing 的狀態。
實際執行代碼
因此要想使得代碼正常運行就要將正常存在ddr時的代碼正常運行,僅刪除和DDR強有關的部分(影響編譯和運行的),然后將代碼運行地址設置到OCM上。
所以,取消對296行的定義改成如下內容。
修改內容
此時如果使用當前版本的fsbl的可執行文件可以正常進行燒寫固化了。但是可能此時還是無法正常啟動,下面步驟用于演示并定位具體問題。
選中helloworld工程創建鏡像工程。
創建鏡像
BootLoader選中剛剛修改好的fsbl.elf。
BootLoader選擇
打開開發板,選擇jtag模式下燒寫,選擇創建好的鏡像和剛剛的fsbl的elf文件。
燒寫配置
正在燒寫....
燒寫
燒寫完成后關掉開發板,切換到flash模式下打開串口觀察應用程序能否正常啟動。在我的開發板FPGA done的指示燈和PL端的LED等都只是閃爍了一下,不能正常啟動。
此時還在flash模式下去嘗試在線燒寫。從調試信息可見,FLASH正常啟動,啟動初始化后存在失敗,單步調試后發現main函數的在570行的LoadBootImage()運行后就會存在上述問題。
定位問題代碼
定位到image_mover.c的436行,發現此處的DDR_END_ADDR的默認定義是0X00,無法正常執行下面的程序。
修改定位
所以這里修改DDR_END_ADDR為片上rom的結束地址。
修改宏定義
再次重復操作,完成鏡像生成后,jtag模式燒寫,flash模式啟動,觀察打印調試信息。從調試信息中可以看到,PS端正常啟動,此時掛在PL端的LED燈也能正常點亮。
打印信息