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

硬件:AM5728開發板;Artix-7開發板
軟件:Linux am57xx-evm 4.4.19;Vivado 2015.2
做者:杭州矢志信息科技有限公司
郵箱:admin@sysjoint.comphp

AM5728外設接口豐富,有V-PORT接口、PCIe、GPMC、USB、UART等等,一般與FPGA之間高速數據通訊能夠選擇V-PORT、PCIe、GPMC,這裏以實現起來最簡單的GPMC爲例,實現了從FPGA到AM5728的高速數據搬運。linux

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

  • GPMC接口介紹

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

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:      片選信號ui

GPMC_nOE:      輸出使能時鐘操作系統

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

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://sysjoint.com/files/dts.zip

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

Linux 下 edmatest 參考代碼:http://sysjoint.com/files/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

相關文章
相關標籤/搜索