唐 星 張春雷 陳 龍 趙成龍 張 冀 瞿佳偉
(四川大學(xué) 制造科學(xué)與工程學(xué)院 成都610065)
在嵌入式系統(tǒng)中,F(xiàn)PGA上電時,需要從外部加載配置文件,該過程被稱為程序加載。在多數(shù)應(yīng)用中,F(xiàn)PGA通過主動讀取的方式從外部存儲器加載程序,該方式只能加載固定的配置,不便于升級更新,且需要額外的存儲器件才能實現(xiàn)[1]。本文設(shè)計了一種對FPGA芯片進行程序加載的接口,通過Cortex-A8微處理器對FPGA進行配置,不需要單獨的存儲器,使用微處理器通用 IO模擬接口時序?qū)崿F(xiàn),配置靈活,不占用專用接口資源,可以在線升級FPGA固件。
本設(shè)計選用的FPGA是Spartan-6 XC6SLX16,該芯片正常工作時配置數(shù)據(jù)保存在SRAM單元中,該單元也被稱為配置存儲器(Configuration RAM)。由于SRAM是易失性存儲器,掉電之后必須重新配置[2]。配置信息通過特定的配置方式加載到芯片里,SPARTAN6 FPGA支持多種配置方式,包括:JTAG配置模式、Master Serial主動串行(Serial/SPI)配置模式(x1、x2 and x4)、Slave Serial被動串行配置模式、Master SelectMAP主動并行模式(x8 and x16)、Slave SelectMAP被動并行模式(x8 and x16)[3]。
主動和被動的區(qū)別在于數(shù)據(jù)采樣的時鐘來源:由FPGA輸出時鐘到存儲器,屬于主動模式,由外部器件給 FPGA提供時鐘,屬于被動模式。XC6SLX16通過兩個模式配置寄存器M[1:0]來確定其使用的模式,該寄存器的值在芯片初始化后通過對 M1、M0兩個管腳采樣進行確定。本設(shè)計采用FPGA的串行從模式進行配置,對應(yīng)的M1、M0引腳均為高電平。開始配置時,微處理器把Program_B引腳電平由高拉低并持續(xù)超過 500ns,強制XC6SLX16進入配置模式,清除片內(nèi) SRAM,Program_B引腳電平變高以后,XC6SLX16將INT和 DONE引腳清零,當(dāng)SRAM清除完畢且 M1,M0引腳采樣完成后,XC6SLX16將INT引腳電平拉高,微控制器此時可以開始通過CCLK和D0引腳發(fā)送配置數(shù)據(jù),XC6SLX16在每個CCLK上升沿時采樣1bit配置數(shù)據(jù)并寫入芯片,如果中途出現(xiàn)校驗錯誤,INT腳將變低報錯,當(dāng)配置成功完成后,XC6SLX16將DONE信號拉高,通知微控制器配置成功。Spartan 6 FPGA串行從模式配置過程的時序如圖1所示。
圖1 Spartan 6 FPGA串行從模式配置接口時序
本設(shè)計選用的微處理器是基于Cortex-A8內(nèi)核的處理器 AM3352,工作頻率為 600MHz,具有NEON/SIMD協(xié)處理器,支持Linux,WinCE操作系統(tǒng),具有豐富的外設(shè)接口[4]。FPGA配置接口使用5個GPIO實現(xiàn),F(xiàn)PGA與固件配置相關(guān)的5個引腳都接到AM3352的GPIO上,F(xiàn)PGA_INT信號用于標識 SRAM 清除完畢,可以開始傳輸數(shù)據(jù),F(xiàn)PGA_PROGRAM 信號用于啟動配置流程,F(xiàn)PGA_DONE信號用于標識配置過程成功完成,AM3352通過這個引腳的信號判斷配置是否成功,F(xiàn)PGA_CCLK信號為AM3352輸出到FPGA的時鐘信號,每個上升沿時,F(xiàn)PGA從FPGA_D0引腳上采集1bit配置數(shù)據(jù)。接口硬件原理如圖2所示。
圖2 配置接口硬件原理圖
配置接口的軟件在運行于AM3352上的Linux中實現(xiàn),接口軟件分為字符設(shè)備驅(qū)動和應(yīng)用程序兩部分。字符設(shè)備驅(qū)動程序?qū)崿F(xiàn)配置 IO的初始化和讀寫以及數(shù)據(jù)寫入的接口,應(yīng)用程序通過調(diào)用驅(qū)動接口實現(xiàn)配置流程[5],軟件模塊構(gòu)架如圖3所示。
圖3 軟件模塊構(gòu)架
驅(qū)動模塊的核心功能是對用來配置FPGA的5個GPIO管腳進行控制,包括引腳的初始化,IO狀態(tài)的讀取和控制,時鐘和數(shù)據(jù)的發(fā)送。根據(jù)AM3352數(shù)據(jù)手冊提供的寄存器表,利用Linux 3.2內(nèi)核中提供的API函數(shù),完成此驅(qū)動程序的編寫,其中模塊加載函數(shù) fpga_config_init()使用 ioremap()函數(shù)完成GPIO置位和清位寄存器的映射,以保證在內(nèi)核中能通過虛擬內(nèi)存地址正確地訪問到硬件寄存器,接著初始化各個IO為正確的上下拉和輸入輸出模式,其中 INT、DONE信號為上拉輸入模式,PROGRAM_B、CCLK、D0為輸出模式。通過register_chrdev()注冊該接口的 file_operations結(jié)構(gòu)體并返回得到驅(qū)動程序的主設(shè)備號,通過class_create()和device_create()接口創(chuàng)建設(shè)備,設(shè)備名稱為 fpga_config,當(dāng)驅(qū)動被加載后,Linux文件系統(tǒng)的/dev目錄下就會出現(xiàn)該設(shè)備。fpga_config_ioctl()接口用于完成對輸出引腳的操作,包括 PROGRAM_B腳、CCLK腳、D0腳。fpga_config_read()接口用于讀取INT、和DONE腳的電平,通過該接口判斷 FPGA當(dāng)前的狀態(tài)。fpga_config_write()用于AM3352向FPGA寫入配置數(shù)據(jù),其中將應(yīng)用程序傳入的數(shù)據(jù)按位賦予D0引腳,然后操作CCLK引腳生成時鐘信號,F(xiàn)PGA在CCLK信號上升沿讀取1bit數(shù)據(jù),為了加快發(fā)送的速率,此處對CCLK和D0腳直接使用寄存器操作設(shè)置高低電平,gpio3SetData和 gpio3ClearData分別為GPIO3的置位寄存器和清位寄存器指針,當(dāng)向gpio3SetData指向的地址寫值時,該值有效位(為1)對應(yīng)的引腳被置高,其余引腳保持不變,當(dāng)向gpio3ClearData指向的地址寫值時,該值有效位(為1)對應(yīng)的引腳被置低,其余引腳保持不變[6]。寫入配置數(shù)據(jù)部分的驅(qū)動示例代碼如下:
//直接操作寄存器以加快速度
應(yīng)用程序部分通過調(diào)用 open()函數(shù)打開配置接口設(shè)備,通過 ioctl()函數(shù)拉低 PROGRAM_B引腳1ms后再拉高來開啟配置,1ms后調(diào)用read()讀取引腳狀態(tài),檢測INT腳是否為高電平,若為高,則開始調(diào)用write()函數(shù),將從文件系統(tǒng)讀取的配置數(shù)據(jù)通過配置接口寫入FPGA,寫入完成后,通過read()函數(shù)讀取DONE信號狀態(tài),判斷配置是否成功。若INT不為高或者DONE信號不為高,則認為FPGA配置失敗并打印錯誤信息。
本實驗平臺為一款嵌入式多軸運動控制器,該控制器基于ARM+FPGA架構(gòu),運行Linux3.2系統(tǒng),具有四軸脈沖方向輸出,最大輸出脈沖頻率為2MHz。運行Linux系統(tǒng)的AM3352負責(zé)實現(xiàn)運動控制,讀取加工文件,主從USB、網(wǎng)絡(luò)、串口等功能,F(xiàn)PGA負責(zé)發(fā)送脈沖控制電機驅(qū)動器以及IO口操作,AM3352通過GPMC接口和FPGA進行數(shù)據(jù)交換,使用本文設(shè)計的配置接口進行FPGA的配置,其系統(tǒng)框圖如圖4所示。
圖4 實驗平臺系統(tǒng)框圖
完成以上代碼編寫后,編寫 makefile,編譯內(nèi)核模塊為 fpga_config.ko和應(yīng)用程序 fpga_loader,編譯器為 arm-linux-gnueabihf-gcc,操作系統(tǒng)為Ubuntu 12.04.5 32位。控制器上Linux系統(tǒng)啟動后,通過 insmod命令加載 fpga_config.ko模塊,配置FPGA開發(fā)工具ISE生成二進制配置文件fpga.bin[7],使用./fpga_loader /firmware/fpga.bin命令加載配置文件,通過200MHz邏輯分析儀采集加載過程的波形如圖5所示。
圖5 配置過程波形
分析波形可得總配置時間為0.46s,CCLK時鐘最大頻率8.33MHz,本設(shè)計使用的FPGA速度等級為2C,串行從模式下該等級最大外部輸入時鐘為80MHz[3],該頻率高于配置過程最大時鐘頻率。通過應(yīng)用程序打印的信息,可知配置及加載成功。
通過AM3352的GPIO模擬FPGA配置接口時序,實現(xiàn)了在線配置FPGA的功能,省去了常見的外接FLASH芯片的成本。這種配置方式實現(xiàn)靈活,不占用微控制器專用接口資源,方便對FPGA固件進行升級和更新操作,達到了設(shè)計要求。