AM5728通過GPMC接口與FPGA高速數據通信實現


轉載請注明出處 :https://www.cnblogs.com/imapla/p/7454973.html

硬件:AM5728開發板;Artix-7開發板
軟件:Linux am57xx-evm 4.4.19;Vivado 2015.2
作者:Imapla
郵箱:hihuanglong@foxmail.com

AM5728外設接口豐富,有V-PORT接口、PCIe、GPMC、USB、UART等等,通常與FPGA之間高速數據通信可以選擇V-PORT、PCIe、GPMC,這里以實現起來最簡單的GPMC為例,實現了從FPGA到AM5728的高速數據搬運。

AM5728的ARM端運行Linux 4.4內核操作系統,通過GPMC接口采用DMA的方式讀取FPGA端的數據,讀取32KB數據大概用了540us,即60MB/s左右的速度,實際上通過配置GPMC接口的時間參數和工作模式,速度還可以更快。

  • GPMC接口介紹

GPMC的全稱是 General-Purpose Memory Controller,即通用存儲控制器,是TI的Sitara 系列處理器AM5728用來與外部存儲設備例如NOR FLASH、NAND FLASH、SRAM等等通信的一個接口。這個接口並不是AM5728特有的,在BeagleBone Black、AM33XX等芯片上也有類似接口。

1.1 硬件連接方式

參考SPRUHZ6I 15.4.6.1.2 在AM5728中把GPMC接口配置為異步模式並設置NOR FLASH、非地址數據線復用的模式與FPGA通信,但只用16位數據線,不用地址線,即采用類似於FIFO的方式與FPGA通信。目前實際只使用到了如下I/O口,信號方向如下圖所示。

GPMC_D[15:0]:  16位數據線

GPMC_nCS:      片選信號

GPMC_nOE:      輸出使能時鍾

FPGA_nRST:     用於通知FPGA讀寫指針復位

FPGA_nIRQ:     用於通知ARM讀取一塊數據

1.2 硬件接口協議

采用異步方式讀取,即不使用GPMC_CLK,FPGA端在GPMC_nOE的下降沿把數據送出去。

目前這種工作模式下的GPMC接口,我們只需要關心以下幾個時間:

即CS有效時間,OE有效時間,GPMC讀取數據時間,GPMC單個讀取周期。

  • Linux驅動實現

Linux 4.4 版本內核采用設備樹dts的方法編寫驅動,與2.6版本時候有較大區別,4.4版本內核中關於GPMC接口的API幾乎沒有導出,通過API來操作不可行,必須使用編寫設備樹方法。關於設備樹的編譯請參考創龍的用戶手冊。

AM5728的dts文件路徑:linux-4.4.19-g5e4091a-v1.3\arch\arm\boot\dts

內核實現的gpmc驅動在:linux-4.4.19-g5e4091a-v1.3\drivers\memory\omap-gpmc.c

關於 dts 的編程方法可以參考:

https://learn.adafruit.com/introduction-to-the-beaglebone-black-device-tree/overview

以及閱讀Linux內核目錄下的文檔:

Documentation\devicetree\bindings\mtd\gpmc-nor.txt

配置方面主要包括與GPMC相關的7個配置寄存器CONFIG1-CONFIG7,GPMC端口初始化等等。

(1)首先確保在 文件dra7.dtsi中引入了GPMC控制器,如下:

(2)接着在 am57xx-beagle-x15-common.dtsi 加入 GPMC 管腳初始化配置

(3)最后在實現一個自己的GPMC設備節點,其中關鍵的時序參數如下,在這里我們設置GPMC的片選CS6地址為0x10000000,大小為16MB,GPMC的單個讀取周期為30ns。

  • 采用DMA傳輸

AM5728帶有System DMA和Enhanced DMA,Linux 4.4 之后內核中 EDMA 相關的API不對外導出,因此暫時只能采用通用的DMA API操作,實現DMA搬運。

需要注意的是,DMA中配置的地址都為物理地址,即DMA傳送到源端為外設的地址即GPMC的物理地址,目的地端為你申請的內存空間物理地址。

  • 實驗驗證

(1)使用memread讀取GPMC端口數據

memread中使用mmap方法把GPMC的物理地址0x10000000映射到用戶空間。在用戶空間通過CPU讀取GPMC端口數據,抓取CS6n和OEn的波形如下,目前沒有用到DMA傳送,只是在Linux循環讀取,可以看見每個周期里片選信號CS6n都會維持很長一段高電平的時間,GPMC一次的讀取周期大概為200ns。

通道1為片選信號CS6n,通道2為輸出使能信號OEn

這樣的速率大概只有 16bit / 200ns = 10MB/s

(2)使用DMA傳輸

編譯並使用insmod工具加載DMA驅動edmatest.ko,抓取CS6n和OEn的波形如下,使用DMA傳送,這下讀周期就小了很多了,大概只有30ns,和GPMC參數里設置的完全一致。讀取32KB數據大概用了540us,即60MB/s左右的速度。實際上通過配置GPMC接口的時間參數和工作模式,速度還可以更快。

(3)FPGA端對應的代碼,FPGA端的代碼只要是實現在每個OEn信號下降沿來的時候,把16bit的數據送到GPMC_DATA端口,並自加一次。

(4)Linux端讀取數據並做校驗

校驗通過,說明數據一致性正確!至此AM5728與FPGA通過GPMC接口用DMA實現數據高速傳輸,驗證可行!

  • 源代碼下載

設備樹文件:http://deepelec.com/files/dsp/dts.zip

Linux 下 memread 參考代碼:http://deepelec.com/files/dsp/memread.zip

Linux 下 edmatest 參考代碼:http://deepelec.com/files/dsp/edmatest.zip

FPGA端對應代碼比較簡單就不上傳了。

整個實驗過程中涉及到的細節很多,如有錯誤之處請不吝指出!

參考資料:

https://e2e.ti.com/support/arm/sitara_arm/f/791/t/512464

https://e2e.ti.com/support/arm/sitara_arm/f/791/p/315716/1530903#pi316653=1

https://github.com/fpga-logi/logi-kernel/commit/42066f774425afb196dc0f8f1ad40f450da34115

http://valentfx.com/wiki/index.php?title=LOGI_-_BBB_GPMC_Bus-_HW

有任何問題,歡迎加入 TI DSP 技術交流 QQ 群:652563558


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM