<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 網(wǎng)絡(luò )與存儲 > 設計應用 > 基于C語(yǔ)言和GEL語(yǔ)言的Flash編程新方法

基于C語(yǔ)言和GEL語(yǔ)言的Flash編程新方法

——
作者: 時(shí)間:2007-12-13 來(lái)源: 收藏

  以為例,探討一種綜合運用、數據文件及的Flash編程新方法。

  該方法完全采用編寫(xiě)燒寫(xiě)程序,解決了指針不能訪(fǎng)問(wèn)高端Flash的問(wèn)題;把引導表作成數據文件,可實(shí)現大引導表的分批次加載;通過(guò)GEL程序控制C程序執行,較好地體現了Flash編程的流程。

  引言

  在DSP應用系統開(kāi)發(fā)的后期,一般需要將用戶(hù)程序寫(xiě)進(jìn)Flash等非易失性存儲器,以便采用并行引導的方法實(shí)現用戶(hù)程序的自舉加載。這一步驟稱(chēng)為“燒寫(xiě)”;針對Flash的燒寫(xiě)又稱(chēng)為Flash編程。以往的編程方法大多采用匯編語(yǔ)言編寫(xiě)程序,可讀性較差,并將引導表的制作也放在程序中實(shí)現;用戶(hù)程序一變,燒寫(xiě)程序就得重新編寫(xiě),不具有通用性。參考文獻[1]采用完成Flash讀寫(xiě),較清晰地體現了Flash編程的思想,但是它采用指針訪(fǎng)問(wèn)Flash空間,不能對高端Flash(64 K字存儲空間以外)進(jìn)行訪(fǎng)問(wèn),且將引導表作成數組的方法仍顯機械。

  這里提出的Flash編程方法完全采用C語(yǔ)言編寫(xiě)燒寫(xiě)程序,運用函數地址訪(fǎng)問(wèn)高端Flash,借助數據文件將引導表加載到數據空間。GEL(General Extension Language,通用擴展語(yǔ)言)作為一種程序擴展語(yǔ)言,被廣泛用于調試及程序運行環(huán)境的定制。這里將運用于Flash編程,可以控制C程序在數據加載完成后執行燒寫(xiě)過(guò)程,從而實(shí)現大引導表的燒寫(xiě)。

  1 DSP開(kāi)發(fā)板及Flash存儲器

  筆者使用的DSP開(kāi)發(fā)板上有1片通用DSP芯片、1片SST39VF400A存儲芯片(Flash)、鍵盤(pán)和液晶顯示器等。其中Flash容量為256 K字(1字=16位),組織為128個(gè)扇區或8個(gè)塊。為充分發(fā)揮Flash容量大的特點(diǎn),本系統在硬件上將Flash空間的映射設計為:在上電自舉過(guò)程中,Flash空間的0x04000~0x0FFFF映射到數據空間的0x4000~0xFFFF;上電自舉完成后,整個(gè)Flash空間0x00000~0x3FFFF映射到程序空間的0x80000~0xBFFFF,即映射到了的擴展程序空間,處于高地址,因此稱(chēng)為“高端Flash”。由此可知,對系統進(jìn)行應用開(kāi)發(fā)時(shí),Flash總是表現為高端Flash。

  

 Flash編程流程

  圖1 Flash編程流程

  2 Flash編程流程

  用戶(hù)程序一般以可執行COFF(公共目標文件格式)文件格式存在(后綴名為.out),Flash編程所要完成的就是將此可執行文件轉換成特定的ASCII碼引導表的格式,并按此格式順序寫(xiě)進(jìn)Flash。Flash編程流程如圖1所示。下面僅以一個(gè)動(dòng)畫(huà)顯示程序qq.out為例,介紹如何將其燒寫(xiě)進(jìn)Flash。

  .1 生成引導表

  通過(guò)Hex轉換工具,將用戶(hù)程序qq.out文件轉換成十六進(jìn)制形式的ASCII碼流文件(ASCIIHex格式文件[2])qq.asc。首先編寫(xiě)一個(gè)convert.cmd命令文件。部分內容如下:

  qq.out/*用戶(hù)程序*/

  -a/*轉換成ASCIIHex格式文件*/

  -map qq.mxp/*包含引導表的長(cháng)度等信息*/

  -o qq.asc/*轉換成qq.asc*/

  執行命令行“hex500 convert.cmd”將產(chǎn)生qq.mxp和qq.asc文件。其中qq.mxp文件有這樣的信息:“CONTENTS: 00000000…0000433b”。表示qq.asc中的引導表長(cháng)度為0x433C字,內容大致為:“10 AA 7F FF 00 02 00 00…”。

{{分頁(yè)}}

  2.2 轉換成數據文件

  編程將ASCIIHex格式文件qq.asc轉換成CCS(Code Composer Studio,代碼集成開(kāi)發(fā)環(huán)境)支持的數據文件(后綴名為.dat)。例中的引導表已屬較大的表,這里將其轉換為兩個(gè)數據文件qq_dat1.dat和qq_dat2.dat,以在同一緩沖區分兩次裝載,避免因緩沖區太小而容納不了引導表的情況發(fā)生。

  CCS支持的數據文件的第一行為文件頭信息,格式為:

  幻數  數據格式  起始地址  頁(yè)類(lèi)型  數據塊大小

  其后是文件內容,每行表示一個(gè)數據。其中幻數固定為“1651”,數據格式可以選擇“1”(十六進(jìn)制整型)、“2”(十進(jìn)制整型)、“3”(十進(jìn)制長(cháng)整型)、“4”(十進(jìn)制浮點(diǎn)型)。

  利用VC6.0編寫(xiě)該轉換程序是簡(jiǎn)單的,程序運行后產(chǎn)生的qq_dat1.dat文件將是:“1651 1 4000 1 2000 0x10AA…”。從文件頭信息可知,加載該文件可將引導表裝載到數據空間0x4000起始的長(cháng)度為0x2000的緩沖區中。

  2.3 Flash燒寫(xiě)

  利用GEL程序將引導表形成的數據文件qq_dat1.dat和qq_dat2.dat逐次裝載到數據空間,調用C程序執行燒寫(xiě)過(guò)程。

  由于Flash空間映射到TMS320VC5402程序空間的0x80000~0xBFFFF,故實(shí)際編寫(xiě)程序時(shí)使用的Flash空間的地址均需偏移0x80000。例如,Flash空間的0x5555地址單元實(shí)際上為0x85555。

  正如前面所介紹的,雖然高端Flash囊括了整個(gè)Flash空間,但是對于C54x系列芯片,其C語(yǔ)言指針的寬度為16位,只能訪(fǎng)問(wèn)64 K字范圍(0x0000~0xFFFF)之內的存儲空間,而不能訪(fǎng)問(wèn)高端Flash(0x80000~0xBFFFF)。

  參考文獻[3]討論了用C語(yǔ)言指針不能訪(fǎng)問(wèn)C54x系列DSP擴展程序空間的問(wèn)題,提出了用函數名代替指針來(lái)訪(fǎng)問(wèn)擴展程序空間的方法,并給出了可供C程序調用的pfunc_ext.lib庫。這一方法本質(zhì)上是將函數名代表的程序空間地址(20位)傳送到40位的累加器,進(jìn)行累加器尋址,因此使用該庫恰好可以解決指針不能訪(fǎng)問(wèn)高端Flash的問(wèn)題。庫中以下兩個(gè)函數是有用的:

  int PFUNC_wordRead(PFUNC addrProg);

  //讀取(擴展)程序空間地址addrProg處的一個(gè)字

  void PFUNC_wordWrite(PFUNC addrProg,int wData);

  //將字wData寫(xiě)到(擴展)程序空間地址addrProg處

  為應用pfunc_ext.lib庫,需定義一些函數,并在命令文件中為這些函數所在的自定義代碼段分配段地址,以使這些函數的函數名指向Flash特定的地址單元。例如,可以編寫(xiě)一個(gè)C程序源文件,定義一個(gè)空函數FLASH_5555以指向0x85555:

  #pragma CODE_SECTION(FLASH_5555,"bigpointer")

  void FLASH_5555(void){}

  Flash的其他地址可依此方法得到, pfunc_ext.lib庫的具體說(shuō)明見(jiàn)參考文獻[3]。

  下面應用pfunc_ext.lib庫編寫(xiě)了Flash擦除和編程的3個(gè)基本函數flash_erase()、flash_word_write()、flash_serial_write(),分別完成Flash擦除、字編程和連續編程。其中連續編程只是循環(huán)調用了字編程函數。擦除和字編程的流程分別如圖2和圖3所示。

{{分頁(yè)}}

  擦除函數的代碼如下:

  //實(shí)現片擦除、塊擦除或扇區擦除,type定義擦除方式,addr給出扇區起始地址或塊起始地址

  unsigned int flash_erase(PFUNC addr,unsigned type){

  //執行SST39VF400A的擦除命令序列

  PFUNC_wordWrite(FLASH_5555,FLASH_CMD1);

  //0xAA﹥*(0x85555)

  …

  PFUNC_wordWrite(addr,type);//擦除類(lèi)型命令

  …

  }

  

擦除流程

  圖2 擦除流程

  

字編程流程

  圖3 字編程流程

  有了這些基本函數,就可以在主函數中完成Flash的燒寫(xiě)。下面的主函數實(shí)現將引導表燒寫(xiě)進(jìn)Flash。

{{分頁(yè)}}

  void main(){

  …

  asm("erase:");//擦除0x80000~0x97FFF,塊擦除

  for(i=0;i<3;i++)

  flag=flash_erase((PFUNC)i,FLASH_BLOCK_ERASE);

  asm("program1:");//連續編程

  flag=flash_serial_write(FLASH_BASE,MEM_BASE,usercode_length1);//FLASH_BASE指向0x84000

  asm("program2:");//連續編程

  …

  asm("program_bootaddr:");//字編程

  flag=flash_write_word(FLASH_FFFF,0x4000);

  }

  例中采用了塊擦除的方式。MEM_BASE是多次加載引導表的緩沖區起始地址,為與數據文件qq_dat1.dat中文件頭對應,應保證MEM_BASE指向0x4000。其方法類(lèi)似于上述函數名的地址分配(使用#pragma DATA_SECTION偽指令)。最后完成字編程,使Bootloader上電時(shí)得以在數據空間的0xFFFF處讀取引導表在數據空間的起始地址,例中為0x4000。

  為使主函數正確執行,需借的運行調試功能,由此設計的GEL程序真正體現了Flash燒寫(xiě)的流程。GEL程序流程如圖4所示,部分代碼如下:

  menuitem "PROGRAMMING";

  hotmenu FlashFiring(){…

  GEL_Load("ProgramFlash.out");//加載C燒寫(xiě)程序

  …

  if(flag){

  GEL_Load("qq_dat1.dat");//加載數據文件

  GEL_Go(program1); //執行連續編程

  …

  GEL_Load("qq_dat2.dat");//加載數據文件

  GEL_Go(program2); //執行連續編程…

  }

  }

{{分頁(yè)}}

  

GEL程序流程

  圖4 GEL程序流程

  GEL程序在C程序每次執行前設定正確的環(huán)境變量并初始化緩沖區。例如,數據文件的長(cháng)度usercode_length1就是需要根據實(shí)際的數據文件長(cháng)度進(jìn)行設定的環(huán)境變量;而在進(jìn)行連續編程之前,需要GEL程序重新加載MEM_BASE緩沖區。

  3 運行結果

  在CCS環(huán)境下選擇File/Load GEL,裝載以上GEL程序,選擇GEL/ PROGRAMMING/FlashFiring,即可實(shí)現Flash燒寫(xiě)。拔掉仿真器,給系統重新上電,可以看到液晶顯示器上QQ企鵝的動(dòng)畫(huà)。

  4 結論

  通過(guò)函數地址可以進(jìn)行Flash的全空間訪(fǎng)問(wèn);采用C語(yǔ)言編寫(xiě)Flash擦除和編程函數,增強了程序的可讀性;將引導表作成多個(gè)數據文件,一方面適于大引導表的加載,另一方面使Flash編程算法與編程數據完全分離,提高了算法的通用性;僅在GEL程序中修改參數即可實(shí)現另一用戶(hù)程序的燒寫(xiě),體現了方法的靈活性。

  參考文獻

  [1] 張勇.C/C++語(yǔ)言硬件程序設計——基于TMS320C5000系列DSP[M].西安:西安電子科技大學(xué)出版社,2003(5):206-230.

  [2] Texas Instruments. TMS320C54x Assembly Language Tools User's Guide. SPRUF102,200-210.

  [3] David M Alter. Using C to Access Data Stored in Program Memory on the TMS320C54x DSP[R]. SPRA177A, Texas Instruments Application Report,2005-08.

  [4] 北京合眾達電子技術(shù)有限公司. SEED——MMI5402用戶(hù)指南. 2004-06.

c語(yǔ)言相關(guān)文章:c語(yǔ)言教程


c++相關(guān)文章:c++教程


存儲器相關(guān)文章:存儲器原理




評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>