• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

      基于Linux系統(tǒng)的FPGA芯片在線加載的設計和實現(xiàn)

      2015-01-16 05:26:50楊鵬
      電子設計工程 2015年6期
      關鍵詞:管腳示例端口

      楊鵬

      (北方民族大學 寧夏 銀川 750021)

      在嵌入式系統(tǒng)設計和開發(fā)過程中,基于FPGA(Field-Programmable Gate Array,現(xiàn)場可編程門陣列)的仿真和功能開發(fā)變得不可或缺。FPGA(Field-Programmable Gate Array,現(xiàn)場可編程門陣列)具有豐富的邏輯設計資源,可以完成復雜的數(shù)據(jù)處理任務以及邏輯控制任務。FPGA所具有的靜態(tài)可重復編程和動態(tài)系統(tǒng)可重構特性,使得硬件的功能可以像軟件一樣可以通過編程來修改,極大地提高了嵌入式系統(tǒng)設計的靈活性和通用性,降低了設計難度,縮短了研發(fā)周期,必將成為未來的嵌入式開發(fā)的主流趨勢之一。

      基于FPGA的開發(fā),是指利用FPGA芯片實現(xiàn)用戶設計要求的全過程[1]。在嵌入式系統(tǒng)中開發(fā)過程中,如何將FPGA芯片的代碼方便快捷的加載運行是要解決的問題。FPGA程序在仿真完成后,上板調試和驗證一般是通過PC機連接硬件設備單板的JTAG口完成代碼加載和運行。但是考慮到批量生產以及后續(xù)在線升級時,通過這種下載方式進行操作則顯得非常繁瑣,并且如果采用手工下載,無法保證所有設備的一致性,易用性很差。如果通過CPU自加載FPGA程序的方式,則只需要把FPGA程序文件燒寫到硬件設備單板的存儲FLASH中,設備上電啟動后,CPU可自行模擬JTAG口時序,讀取文件數(shù)據(jù)并完成在線加載過程。本文就提出了一種對Lattice系列FPGA芯片進行程序在線加載的設計和實現(xiàn)過程。

      1 系統(tǒng)設計

      1.1 芯片加載過程分析

      Lattice系列FPGA芯片片內包含SRAM和Flash兩種存儲器。SRAM包含了FPGA的配置信息。Flash為這些配置信息提供了內部存儲空間。Lattice系列FPGA的程序加載方式如圖1所示。

      圖1 Lattice系列芯片程序加載方式Fig.1 Lattice series chip program loading method

      可以看出Flash可以通過JTAG口和slave parallel方式下載。 SRAM 則可以通過 JTAG、slave parallel、master serial、slave serial方式進行下載。SRAM中的數(shù)據(jù)是易失的,F(xiàn)lash中的數(shù)據(jù)是非易失的。所以我們最終目的是用CPU模擬JTAG時序實現(xiàn)FPGA程序自加載到flash中。

      JTAG時序模擬部分主要是對 TCK、TMS、TDI、TDO等信號線進行操作,并最終表現(xiàn)為控制TAP控制器的狀態(tài)轉換。主要的接口函數(shù)有:設置TMS、發(fā)送TCK時鐘脈沖、設置TDI、讀取TDO數(shù)據(jù)進入下一狀態(tài)機狀態(tài)、讀寫數(shù)據(jù)寄存器、寫指令寄存器、讀目標機CPU設備ID、選擇掃描鏈、初始化JTAG口等[2]。Lattice公司提供了C語言代碼框架,命名為ispvme。此種方法不占用gpio,下載時序相對簡單。JTAG狀態(tài)機已經在代碼中封裝好,只需改動和單板的驅動接口即可。ispvme的流程如圖2所示。

      圖2 Ispvme流程圖Fig.2 Ispvme flow chart

      從上圖中可以看出,最終下載的文件是vme文件。把vme文件作為源數(shù)據(jù),每次更新版本時,只需要更新vme文件即可[3]。

      1.2 軟件設計思路

      本系統(tǒng)所運行的硬件設備采用Linux作為其操作系統(tǒng)。Linux系統(tǒng)有一個很好的特性:內核提供的特性可以在運行時進行擴展。這意味著當系統(tǒng)啟動并運行時,我們可以向內核添加功能,當然也可以在不用時動態(tài)移除該功能。Linux系統(tǒng)支持很多種模塊類型,包括設備驅動程序。將設備驅動程序編譯為可動態(tài)加載的模塊(.ko文件),當系統(tǒng)啟動運行后使用insmod加載該設備驅動模塊,上層應用軟件可調用模塊提供的接口對硬件進行操作,當操作完成后,可使用rmmod命名卸載該設備驅動模塊[4]。

      根據(jù)本系統(tǒng)運行的軟件平臺(Linux2.6.22),將此功能模塊設計由兩層來完成。一是實現(xiàn)基于Linux的設備驅動層,主要是完成對GPIO管腳初始化配置,并進行具體的讀寫操作用來產生模擬時鐘、數(shù)據(jù)和控制等信號。二是上層應用程序,即Lattice公司提供的C語言代碼框架,它調用底層驅動模塊接口,模擬JTAG時序對vme文件進行處理,完成實際的FPGA代碼自動加載功能。整個模塊的工作原理框圖如圖3所示。

      圖3 軟件側模塊構架Fig.3 Software architecture

      根據(jù)模塊的設計思路,整個開發(fā)流程分以下3步進行:

      1)生成xxx.vme文件,生成xxx.vme文件的原理和流程在上文中已講述過。

      2)實現(xiàn)Linux驅動側代碼,編譯生成動態(tài)可加載模塊(ko文件);

      3)對Lattice公司提供的C語言代碼框架中的 hardware.c文件進行移植修改,包括讀寫端口、延時函數(shù)以及時鐘產生函數(shù)等,編譯生成可執(zhí)行文件。

      1.3 軟件實現(xiàn)過程

      1)驅動側代碼實現(xiàn)

      本驅動模塊的核心功能是對用來模擬JTAG時序的四個GPIO管腳進行控制,包括對管腳工作模式的配置、輸入輸出方向的配置以及電平狀態(tài)的控制 (如果管腳配置為輸出)和管腳狀態(tài)的讀?。ㄈ绻苣_配置位輸入),并提供對應用層的操作接口以供調用。根據(jù)本設備所使用的處理器datasheet中GPIO接口寄存器的相關定義[5],并利用Linux2.6.22內核中提供的對本處理器GPIO管腳進行操作的內核API函數(shù),完成此驅動模塊開發(fā)。在驅動程序的模塊初始化函數(shù)中首先完成對管腳的配置,示例代碼如下:

      static int onlineloading_init(void)

      {

      u32 viraddr;

      ret=misc_register(&load_miscdev);

      if(ret<0)

      return ret;

      viraddr=ioremap_nocache(XX_CTRL_BASE, 0xff);

      /*配置管腳為gpio模式*/

      *(u8*)(viraddr+0xF9)=0x03;

      *(u8*)(viraddr+0xFA)=0x03;

      *(u8*)(viraddr+0xFB)=0x03;

      *(u8*)(viraddr+0xFC)=0x03;

      iounmap(viraddr);

      /*申請gpio管腳*/

      request_gpio(5);

      set_gpio_direction(5,1);

      request_gpio(6);

      request_gpio(7);

      request_gpio(8);

      }

      printk("info:load onlineloading module successfully! ")

      }

      2)在ioctl函數(shù)中實現(xiàn)向應用程序層的操作接口。示例代碼如下:

      static int load_ioctl (struct inode*inode, struct file*file,unsigned int cmd, unsigned long arg)

      {

      unsigned short port;

      unsigned short value;

      unsigned char read_value;

      unsigned char getparam[2]={0x0,0x0};

      switch (cmd) {

      case write_port://寫GPIO端口,命令參數(shù)由應用層傳入

      if(copy_from_user(getparam,arg,2)) {

      printk("copy fpga load write_port value error ");

      return -EFAULT;

      }

      port=getparam[0];

      value=getparam[1];

      set_gpio_direction(port,0); //將管腳配置為輸出模式

      set_gpio_dataout(port,value);

      break;

      case read_port://讀GPIO端口

      read_value=get_gpio_datain(g_ucPinTDO);

      if(copy_to_user(arg,&read_value,sizeof(unsigned long))

      {

      printk("copy fpga load read_port value error ");

      return -EFAULT;

      }

      break;

      default:printk("load module:No valid command! ");

      }

      return 0;

      }

      在ioctl函數(shù)里實現(xiàn)了具體的對GPIO管腳操作的過程。cmd參數(shù)用來傳遞讀寫命令,arg參數(shù)用來傳遞端口號和端口值[6]。

      3)應用程序中hardware.c文件里的讀寫端口、時鐘產生函數(shù)以及延時函數(shù)的修改。示例代碼如下:

      ①根據(jù)硬件連接對管腳進行定義

      const unsigned char g_ucPinTDI=5;/*gpio_5 pin,TDI*/

      const unsigned char g_ucPinTCK=6;/*gpio_6 pin,TCK*/

      const unsigned char g_ucPinTMS=7;/*gpio_8 pin,TMS*/

      const unsigned char g_ucPinTDO=8;/*gpio_9 pin,TDO*/

      ②寫端口函數(shù)的修改。示例代碼如下:

      void writePort (unsigned char a_ucPins,unsigned char a_ucValue)

      {

      unsigned int write_value=0;

      unsigned char param[2]={0x0,0x0};

      param[0]=a_ucPins;

      param[1]=a_ucValue;

      ioctl( fd, write_port, param);//調用驅動模塊,完成寫端口過程

      }

      ③讀端口函數(shù)的修改。示例代碼如下:

      unsigned char readPort()

      {

      unsigned char ucRet=0;

      unsigned long read_value=0;

      ioctl( fd, read_port, &read_value); //調用驅動模塊,完成讀端口過程

      ucRet=(unsigned char)read_value;

      return (ucRet);

      }

      ④時鐘產生函數(shù)的修改。示例代碼如下:

      void sclock()

      {

      unsigned short IdleTime=0;//change to>0 if need to slow down TCK

      unsigned short usIdleIndex=0;

      IdleTime=1;

      for(usIdleIndex=0;usIdleIndex

      writePort( g_ucPinTCK, 0x01 );

      }

      for(usIdleIndex=0;usIdleIndex

      {

      writePort( g_ucPinTCK, 0x00 );

      }

      }

      時鐘產生函數(shù)中的IdleTime參數(shù),用來控制模擬時鐘速率的大小,如果要降低模擬時鐘的速率,則將IdleTime參數(shù)的值變大即可,在實際應用時應視具體情況而定。

      ⑤延時函數(shù)的修改

      hardware.c中提供的延時函數(shù)為ispVMDelay,它實現(xiàn)了比較精確的毫秒級延時。其中的g_usCpu_Frequency參數(shù)為處理器的頻率(單位為M),在實際應用時,應根據(jù)系統(tǒng)具體采用的處理器特性對處理器頻率進行定義。

      修改完 hardware.c后,編寫Makefile文件,對程序進行編譯生成可執(zhí)行文件FPGA_BIN_LOAD。

      2 實驗應用

      當完成以上代碼編寫和修改后,編譯生成可執(zhí)行文件,并將這些可執(zhí)行文件以及要加載的程序文件xxx.vme通過網口下載到設備單板的FLASH上,Linux系統(tǒng)啟動后,可在文件系統(tǒng)下看到這些文件。在線加載過程由以下步驟完成:

      第一步,加載驅動模塊。當系統(tǒng)啟動后,采用insmod命令動態(tài)加載驅動程序編譯生成的動態(tài)加載模塊文件,Linux驅動模塊加載成功。

      第二步,運行FPGA自動加載應用程序。將應用程序編譯生成的FPGA_BIN_LOAD可執(zhí)行文件和FPGA代碼生成的xxx.vme文件拷貝到同級目錄下,執(zhí)行FPGA_BIN_LOAD,系統(tǒng)開始處理xxx.vme文件,F(xiàn)PGA代碼加載過程正在進行。當整個FPGA代碼加載完成后,程序給出打印信息通知用戶,表明加載成功。

      3 結論

      文中提出的通過CPU模擬時序并結合Ispvme的在線下載方式,適用于lattice XO XP XP2 3種系列的可編程器件。這3個系列的器件都是采用內部非易失flash存儲程序。這種在線下載方式,尤其適合在開發(fā)的后續(xù)階段對fpga版本的更新和升級操作。實際應用表明,該系統(tǒng)具有穩(wěn)定性高、操作便捷、易用性強以及可移植性強等特點,達到了設計要求。

      參考資料:

      [1]竇建華,孫強,陸俊鋒.基于JTAG和FPGA的嵌入式SOC驗證系統(tǒng)設計與實現(xiàn)[J].合肥工業(yè)大學學報:自然科學版,2009(3):126-129.DOU Jian-hua,SUN Qiang,LU Jun-feng.Design of the embedded SOC verification system based on JTAG and FPGA[J].Journal of Hefel University of Technology:Natural Science,2009(3):126-129.

      [2]胡貫榮,陳招偉,羅威.一種JTAG驅動實現(xiàn)技術研究[J].計算機工程與科學,2009(2):64-67.HU Guan-rong,CHEN Zhao-wei,LUO Wei.A study of the JTAG driver implementation[J].Computer Engineering and Science,2009(2):64-67.

      [3]LatticeXP Family Handbook.HB1001 Version 02.9[R].Lattice semiconductor,April,2007.

      [4]魏永明,耿岳,鐘書毅,等.LINUX設備驅動程序[M].北京:中國電力出版社,2005.

      [5]Omap 2530 TRM.SWPU090R-June 2005-Revised[R].Texas Instruments,August,2007.

      [6]Neil Matthew,Richard Stone著.LINUX程序設計[M].陳健,宋健健,譯.北京:人民郵電出版社,2010.

      猜你喜歡
      管腳示例端口
      大還是小
      一種端口故障的解決方案
      科學家(2021年24期)2021-04-25 13:25:34
      2019年高考上海卷作文示例
      常見單位符號大小寫混淆示例
      山東冶金(2019年5期)2019-11-16 09:09:22
      “全等三角形”錯解示例
      端口阻塞與優(yōu)先級
      基于圖像處理的異型電子元器件管腳偏移誤差檢測方法研究
      CMOS數(shù)字IC管腳電容的估算與測量
      初識電腦端口
      電腦迷(2015年6期)2015-05-30 08:52:42
      生成樹協(xié)議實例探討
      永定县| 孙吴县| 嘉峪关市| 温泉县| 浦江县| 清新县| 内乡县| 峨眉山市| 保靖县| 三穗县| 伊通| 峨边| 深州市| 芦山县| 德格县| 祥云县| 册亨县| 兴文县| 海南省| 鹿邑县| 昭平县| 巩义市| 扬中市| 乌审旗| 南宫市| 华坪县| 来凤县| 晋江市| 衡水市| 南雄市| 阜宁县| 固阳县| 荣昌县| 无锡市| 两当县| 邵东县| 抚顺市| 永寿县| 滨海县| 海宁市| 安康市|