1)摘自【正點原子】領航者 ZYNQ 之嵌入式開發指南
2)實驗平臺:正點原子領航者ZYNQ開發板
3)平臺購買地址:https://item.taobao.com/item.htm?&id=606160108761
4)全套實驗源碼+手冊+視頻下載:http://www.openedv.com/docs/boards/fpga/zdyz_linhanz.html
5)對正點原子FPGA感興趣的同學可以加群討論:876744900
6)關注正點原子公眾號,獲取最新資料
第三十六章基於TCP協議的遠程更新QSPI Flash實驗
在《程序固化實驗》中,我們了解了如何通過SDK軟體將BOOT.bin文件固化到QSPI中,這種現場通過SDK軟體固化的方式很常用,重新固化也很方便。然而在實際應用中,通過SDK軟體固化或重新固化QSPI並不一定可行,如產品量產發布後進入維護升級階段,若需要修改、更新QSPI中的BOOT.bin文件,遇到產品安放在高危環境中或產品整合到大型機械內部,或產品生產時沒有預留JTAG口,而是預先將程序固化到QSPI中等情況,使用SDK軟體現場重新固化就不可行。此時通過網絡遠程更新QSPI的方式將顯得極其重要和方便。本章我們將介紹如何使用TCP協議實現遠程更新QSPI。本章包括以下幾個部分:
3636.1簡介
36.2實驗任務
36.3硬體設計
36.4軟體設計
36.5下載驗證
36.1簡介
在《程序固化實驗》中我們可以看到,將生成的BOOT.bin文件燒寫到QSPI中就完成了程序固化,其實質是將BOOT.bin文件的數據寫入到QSPI中。將數據寫入到QSPI中的方式有多種,通過SDK軟體工具使用JTAG接口寫入是一種常用的方式。除此之外,我們在《QSPI讀寫實驗》通過調用相關函數操作QSPI向QSPI中寫入數據也是一種常用的方式。顯然,遠程更新QSPI使用的是後一種方式。
遠程更新QSPI就是將BOOT.bin文件通過網絡協議如常用的TCP、UDP協議傳給遠端聯網的文件接收端即領航者開發板。接收端將文件暫存在DDR3中,當文件傳輸完成後,接收端接收到更新命令後將調用相關函數將文件數據寫入到QSPI中,寫入完成後為了防止寫入出錯,需要將寫入到QSPI中的數據讀出以進行校驗。校驗成功後就可以重新以QSPI啟動的方式啟動,完成遠程更新。
從上述可以看出,接收端的領航者開發板作為服務端,發送端作為客戶端將BOOT.bin文件數據上傳給服務端是一個較好的客戶/伺服器模型。有一個特別需要注意的地方是,當客戶端上傳完文件後,作為服務端的領航者開發板如何知道文件傳輸完成並啟動更新呢。
有兩種方式可以解決。一是客戶端傳輸完成後,關閉連接,服務端知道客戶端關閉連接後知道文件傳輸完成,更新QSPI。此種方式弊端很多,如不能知道後續的更新情況,若發生寫入到QSPI錯誤,不能及時修復,以及不能避免因環境問題導致的網絡誤關閉。另一種是當客戶端傳輸文件完成後,向服務端發送更新命令,服務端接收到更新命令後啟動更新。為了防止傳錯文件等意外情況,也可以添加清除命令,使之前傳送的數據無效。
由於TCP協議的穩定可靠,本章我們選擇TCP協議作為網絡傳輸協議。領航者開發板利用lwip協議棧開啟TCP服務作為服務端,可以寫一個TCP客戶端的上位機或使用網絡調試助手開啟TCP客戶端傳送BOOT.bin文件。
最後我們比較下通過SDK軟體更新(使用JTAG接口方式)和網絡更新方式的優缺點。
表 36.1.1 更新方式比較
36.2實驗任務
本章的實驗任務是使用LWIP協議棧的tcp協議實現遠程更新QSPI的功能,當輸入「update」命令時更新QSPI並反饋信息,當輸入「clear」命令時之前傳輸的數據無效。
36.3硬體設計
根據實驗任務我們可以畫出本次實驗的系統框圖,如下圖所示:
圖 36.3.1 系統框圖
在圖 5.3.1中,UART用於列印程序相關的信息,LWIP通過乙太網傳輸文件數據,傳輸的BOOT.bin文件數據寫入到QSPI中。
step1:創建Vivado工程
本次實驗的硬體設計只需在《LWIP echo server》實驗的基礎上添加QSPI即可。
1-1 我們先打開《LWIP echo server》實驗的Vivado工程,打開後將工程另存為 「qspi_update_tcp」工程。
step2:使用IP Integrator創建Processing System
2-1 在Vivado界面左側的Flow Navigator中,點擊IP INTEGRATOR下的Open Block Design以打開Diagram窗口。然後在右側打開的Diagram界面中雙擊ZYNQ Processing System模塊修改其配置,即使能QSPI,如下圖所示:
圖 36.3.2 使能QSPI Flash控制器
2-3 配置完成後點擊「OK」。然後在Diagram窗口空白處右擊,然後選擇「Validate Design」驗證設計。驗證完成後彈出對話框提示「Validation Successful」表明設計無誤,點擊「OK」確認。最後按快捷鍵「Ctrl + S」保存設計。
step3:生成頂層HDL
在Source面板中,右鍵點擊Block Design設計文件「system.bd」,然後執行「Generate Output Products」。
step4:生成Bitstream文件並導出到SDK
由於本實驗未用到PL部分,所以無需生成Bitstream文件,只需導出到SDK即可。如果使用到PL,則需要添加引腳約束以及對該系統進行綜合、實現並生成Bitstream文件。
4-1 導出硬體。
在菜單欄中選擇 File > Export > Export hardware。
並在彈出的對話框中,取消勾選「Include bitstream」,直接點擊「OK」按鈕。
因為是在前一工程的基礎上建立的,還保留著前一工程的結果,所以會彈出「Module Already Exported」對話框,我們點擊「Yes」按鈕。
4-2 硬體導出完成後,選擇菜單File->Launch SDK,啟動SDK開發環境。
36.4軟體設計
本次實驗的軟體設計與《LWIP echo server》實驗無本質差別,程序框架保持不變,主要是將《LWIP echo server》實驗的echo.c文件實現的功能改寫成需求的遠程更新QSPI功能,可在《LWIP echo server》實驗的基礎上修改,但為了方便程序的管理,此處我們刪除《LWIP echo server》實驗的應用工程,保留bsp工程。下面我們開始第五步——創建應用工程。
step5:在SDK中創建應用工程
5-1 在菜單欄中選擇File->New->Application Project, 新建一個SDK空應用工程。
在彈出的界面中,輸入工程名「qspi_update_tcp」,注意Board Support Package選擇「Use existing」,然後選擇「Next >」,如下圖所示,在下一界面選擇「Empty Application」。
圖 36.4.1 新建SDK應用工程
5-2 大家可以從提供的例程中拷貝SDK的源文件,需拷貝的文件如下:
圖 36.4.2 源文件
main.c文件和平臺相關文件platform.h、platform_config.h、platform_zynq.c與《LWIP echo server》實驗中的相同,是使用lwip的通用源碼文件,剩下的三個源文件是我們本實驗的主要功能文件。其中qspi_driver.c是QSPI的驅動文件,主要包括QSPI的初始化和更新QSPI功能、qspi_remote_update.c是程序的核心文件,實現TCP伺服器功能並接收客戶端發送來的文件以及響應客戶端的命令、qspi_remote_update.h是聯繫qspi_remote_update.c與qspi_driver.c的頭文件。下面我們對主要內容進行講解。
5-2 主要內容講解
首先我們來看qspi_remote_update.h頭文件,其內容如下:
在《LWIP echo server》實驗的echo.c文件中我們並沒有用上transfer_data()函數,此處我們將transfer_data()函數用做更新QSPI的起始函數。當發送方發送「update」更新命令時,程序將開始更新標誌start_update_flag置1,從而使transfer_data()函數得以調用qspi_update()函數更新QSPI。transfer_data()函數在main函數的while(1)循環中被調用。
5-11 lwip設置
為了提高數據傳送的效率,我們對lwip進行相應設置。右鍵點擊bsp工程lwip_server_bsp,在彈出的菜單中選擇「Board Support Package Settings」,如下圖所示:
圖 36.4.3 打開BSP設置
在打開的界面中,點擊standalone下的lwip202,設置右側界面的選項。主要設置的選項如下:
設置lwip_memory_options選項。將mem_size設置為524288,增加可得到的總的堆空間;將memp_n_pbuf設置為1024,增加pbuf數;將memp_n_tcp_seg設置為1024,提高同時排隊的TCP段數。如下圖所示。
圖 36.4.4 設置lwip_memory_options選項
設置pbuf_options選項。將pbuf_pool_size為pbuf池中的緩衝區數量。對於高性能系統,可以考慮將pbuf池大小增加到一個較高的值,此處設為16384,如下圖所示。
圖 36.4.5 設置pbuf_options選項
設置tcp_options選項,將tcp_snd_buf和tcp_wnd設為65535,增大tcp發送緩衝空間和窗口大小,如下圖所示:
圖 36.4.6 設置tcp_options選項
設置temac_adapter_options選項,將n_rx_descriptors 和n_tx_descriptors設置為512,以提高系統性能,如下圖所示
圖 36.4.7 設置temac_adapter_options選項
其餘選項保持默認即可,無需修改。
36.5下載驗證
首先我們將下載器與領航者底板上的JTAG接口連接,下載器另外一端與電腦連接。然後使用Mini USB連接線將USB UART接口與電腦連接,用於串口通信。使用網線一端連接領航者開發板的乙太網接口,另一端與電腦或路由器連接。最後連接開發板的電源,並打開電源開關。
現在進入最後一步。
step6:板級驗證
6-1 在SDK軟體的下方的SDK Terminal窗口中點擊右上角的加號連接串口。
6-2 下載程序。下載完成後,可以看到串口列印的結果如下:
圖 36.5.1 顯示列印結果
如果接到路由器,因為有DHCP伺服器,可自動獲取IP 給開發板;如果沒有DHCP 伺服器,則當領航者開發板DHCP超時時使用默認IP 地址:192.168.1.10,埠號為設置的6789。圖 36.5.1中紅框圈起來的,表示QSPI初始化成功。
6-3 遠程更新QSPI
打開網絡調試助手,在網絡調試助手發送區設置裡選擇「啟用文件數據源」,選擇需要發送的BOOT.bin 文件,這裡我們選擇《程序固化實驗》生成的BOOT.bin 文件,然後點擊發送,如下圖所示:
圖 36.5.2 加載BOOT.bin 文件
傳輸完成後,輸入更新QSPI命令「update」,如下圖所示:
圖 36.5.3 輸入更新QSPI命令「update」
輸入更新QSPI命令「update」後,啟動QSPI更新,更新信息實時通過網絡傳送回發送方,顯示在網絡調試助手中,如下圖所示:
圖 36.5.4 實時反饋的更新進度信息
通過傳送回的文件大小,可以了解到傳送過程中有沒有丟包。更新進度信息中的Elapsed time表明每個操作(擦除、寫入、校驗)所花費的時間。
此時,接收方也會通過串口實時輸出更新信息,如下圖所示:
圖 36.5.5 接收方通過串口實時輸出更新信息
校驗成功後,關閉電源開關。將領航者核心板上的啟動模式開關左邊撥到上面(置為1),右邊撥到下面(置為0),即設置為由QSPI Flash啟動,然後再次打開電源開關。
電源開關打開後,核心板上PL配置完成的指示燈點亮。然後每次按下底板上PL_KEY0,可以改變核心板上LED2的顯示狀態,說明遠程更新QSPI成功,本次實驗在領航者ZYNQ開發板上面下載驗證成功。