• 
    

    
    

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

      DSP覆蓋(Overlay)程序設計

      2014-01-15 10:00:46李尚柏
      電子設計工程 2014年21期
      關鍵詞:拷貝存儲器程序設計

      吳 潔,李尚柏

      (四川大學 原子核科學技術研究所 輻射物理及技術教育部重點實驗室,四川 成都 610064)

      通常DSP程序是被加載到DSP的內部存儲器中執(zhí)行的。調試過程中,用CCS集成環(huán)境將編譯好的代碼通過JTAG接口下載到DSP的內部存儲器執(zhí)行;調試完成后,將程序代碼燒錄到DSP的外部存儲器,在 DSP上電時,自動將程序代碼裝載到內部存儲器執(zhí)行[1]。但是,DSP的內部存儲器有限的。如果程序代碼及其使用的數(shù)據(jù)區(qū)大于DSP的內部存儲器,就會限制DSP程序的開發(fā)。解決這種困局的一個有效的方法是使用Overlay程序設計技術。

      早期計算機的內存是非常小的,又要完成較為復雜的任務,開發(fā)人員提出了Overlay的程序設計思想。隨著大規(guī)模集成電路技術的發(fā)展,擁有更多的計算機內存已不是奢望,Overlay技術似乎已逐漸被遺忘。然而,對嵌入式系統(tǒng)和DSP而言,內部存儲器仍然是稀缺資源,Overlay技術仍然具有用武之地[2]。本文將討論DSP Overlay程序的設計技術和實現(xiàn)步驟,并通過一個具體的實例在C6000系列DSP上來實現(xiàn)Overlay程序設計技術。

      1 鏈接命令文件

      在DSP上,對目標系統(tǒng)存儲器的配置以及對段(代碼段、數(shù)據(jù)段等)的配置是實現(xiàn)Overlay的關鍵技術之一。鏈接命令文件是一個以.cmd為后綴的文本文件,其主要用途就是定義目標存儲器的模型,以及指定模塊要加載的位置。它包含:要鏈接的目標文件名、鏈接器選項、MEMORY指令(定義目標系統(tǒng)的存儲器的配置)、SECTIONS指令 (定義段在目標系統(tǒng)中的配置)。表1給出了鏈接命令文件中主要的保留字。

      表1 命令鏈接文件主要保留字Tab.1 The main reserved words of command link file

      UNION:產生一個聯(lián)合段,其中的輸出段具有相同的運行地址。當程序代碼很大,不能加載到目標系統(tǒng)的內部存儲器中執(zhí)行時,希望互相獨立的段運行在相同的地址[3]。

      2 Overlay源程序設計

      本文討論的DSP Overlay程序設計主要是解決內存資源不足的問題,方法是用若干模塊構建一個聯(lián)合段,使聯(lián)合段中各成員模塊共享一塊運行內存,需要執(zhí)行哪個模塊就把它從裝載內存復制到運行內存來執(zhí)行。由此可見,聯(lián)合段中的成員模塊具有互斥性,也就是說,在同一時間只能運行一個聯(lián)合段中的模塊。因此,本DSP Overlay源程序的設計就是把要完成的任務合理的劃分成多個功能模塊[4]。

      2.1 Overlay設計實例

      在本DSP Overlay程序設計實例中,設計了4個功能模塊和兩個公用模塊。每個功能模塊的源代碼分別存儲為獨立的源文件task1.c(計算出兩個整數(shù)的和,再乘以比例系數(shù)ratio)、task2.c(調用公共函數(shù) IntSub,并返回 IntSub 的結果)、task3.c(計算兩個整數(shù)的積)、task4.c(計算兩個整數(shù)的平方和)。公用模塊vectors.asm包含中斷矢量的映射,main.c包含硬件設備的初始化、中斷服務程序和公用函數(shù)。鏈接命令文件overly.cmd是每個DSP程序不可或缺的。命令鏈接文件是Overlay設計的關鍵,下面將重點討論其使用和Overlay程序的設計思想。

      1)鏈接命令文件overlay.cmd,如程序1所示:程序1鏈接命令文件

      /*目標系統(tǒng)存儲器配置*/

      MEMORY

      {

      RAM :origin=0x00000000,len=0x010000/*數(shù)據(jù)存儲器*/

      OVLMEM :origin=0x00010000,len=0x010000/*Overlay模塊運行存儲器*/

      ROM :origin=0x00020000,len=0x020000/*程序存儲器*/

      SDRAM :origin=0x80000000,len=0x1000000/*擴展存儲器*/

      }

      /*段配置*/

      SECTIONS

      {

      .vectors>ROM /*中斷映射段配置*/

      .text >ROM /*公共代碼段配置*/

      .bss >RAM /*未初始化數(shù)據(jù)段配置*/

      .cinit>RAM /*已初始化數(shù)據(jù)段配置*/

      .const>RAM /*常數(shù)段配置*/

      .far >RAM /*遠指針段配置*/

      .stack >RAM /*堆棧段配置*/

      .cio >RAM /*流式I/O函數(shù)緩沖區(qū)配置*/

      .sysmem>RAM/*系統(tǒng)堆內存段配置*/

      /*聯(lián)合段配置*/

      UNION

      {

      .task12:{debug ask1.obj (.text), debug ask2.obj(.text)}

      load >> SDRAM, table (BINIT),table(_task12_ctbl)

      .task34:{debug ask3.obj (.text), debug ask4.obj(.text)}

      load>>SDRAM, table(_task34_ctbl)

      }run=OVLMEM

      .ovly:{}>RAM/*聯(lián)合段拷貝表段配置*/

      .binit:{}>RAM/*引導時的聯(lián)合段拷貝表配置*/

      }

      在上述程序1MEMORY命令中,定義了目標系統(tǒng)的存儲器配置,設置了數(shù)據(jù)存儲器 (RAM)、聯(lián)合段模塊運行存儲器(OVLMEM)、程序存儲器(ROM)、擴展存儲器(SDRAM)的起始地址和長度。在SECTIONS命令中,首先定義了輸出段的配置,將可執(zhí)行代碼段 (.text和.vectors)配置到程序存儲器(ROM), 將 其 它 的 數(shù) 據(jù) 段 (.bss、.cinit、.const、.far、.cio 和 .sysmem)配置到數(shù)據(jù)存儲器(RAM);其次還配置了聯(lián)合段,在聯(lián)合段中使用的table(arg)算符使得鏈接器生成了一個拷貝表(此拷貝表必須具有唯一的名字),同時用arg生成一個變量名,應用程序可以用這個變量名訪問拷貝表。如果指定table(BINIT)(arg為BINIT),則鏈接器產生一個引導時的拷貝表,也即產生一個默認的拷貝表段,供系統(tǒng)初始加載時使用[5]。

      圖1 實例的內存配置和段配置Fig.1 The instance of memory configuration and section configuration

      本程序設計中,鏈接器根據(jù)鏈接命令文件(程序1)產生的目標系統(tǒng)內存配置和段配置如圖1所示。圖中左側部分是MEMORY所定義的系統(tǒng)存儲器配置,右側部分是根據(jù)SECTIONS的描述產生的模塊定位信息。鏈接器把所有的數(shù)據(jù)段定位到RAM存儲器。實際使用數(shù)據(jù)空間的段依次為系統(tǒng)堆棧段.stack(長度為 0x7d0)、已初始化數(shù)據(jù)段.cinit(長度為 0x264)、遠指針段.far(長度為 0x250)、常數(shù)段.const(長度為 0x20)、未初始化段.bss(長度為 0x14)、拷貝表段.ovly(長度為0x20)、引導加載拷貝表段.binit(長度為0x10)。鏈接器把代碼段.text定位在ROM存儲器,占用存儲空間0x20a0字節(jié)。聯(lián)合段的.task12和.task34分別定位在SDRAM存儲器的0x8000000和0x80000100處,分別占用存儲空間0x100和0x0e0字節(jié)。當程序運行時,根據(jù)需要把聯(lián)合段的成員拷貝到OVLMEM存儲空間來執(zhí)行。

      對本DSP Overlay程序設計實例的工程項目編譯鏈接后,打開映射文件(*.map)可以看到鏈接器產生的詳細信息,下面給出內存配置信息、段定位信息和拷貝表信息:

      ①內存配置信息(MEMORY CONFIGURATION)

      name origin length used attr fill

      RAM 00000000 00010000 00000d00 RWIX

      OVLMEM 00010000 00010000 00000100 RWIX

      ROM 00020000 00040000 00001fa0 RWIX

      SDRAM 80000000 01000000 000001e0 RWIX

      由于本實例比較簡單,所以內存的使用也較少。對于復雜的任務,或內存資源較少的目標系統(tǒng),ROM空間可能不足以加載所有代碼。

      ②段定位信息(SECTION ALLOCATION MAP)

      output attributes/

      section page origin length input sections

      -------- ----- ---------- ----------

      .task12 0 80000000 00000100 RUN ADDR=00010000

      80000000 000000c0 task1.obj(.text)

      800000c0 00000040 task2.obj (.text)

      .task34 0 80000100 000000e0 RUN ADDR=00010000

      80000100 00000080 task3.obj (.text)

      80000180 00000060 task4.obj (.text)

      .ovly 0 00000cd0 00000030

      聯(lián)合段.task12和.task34的運行地址均為0x00010000,但各自的加載地址不同,.task12的加載地址為0x80000000,.task34的加載地址為0x80000100??截惐矶?ovly起始地址為0x00000cd0,長度為 0x30,包含 _task12_ctbl、_task34_ctbl和BINIT3個表項。

      ③拷貝表信息(LINKER GENERATED COPY TABLES)

      _task12_ctbl@ 00000cd0 records:1, size/record:12,table size:16

      .task12:copy 256 bytes from load addr=80000000 to run addr=00010000

      _task34_ctbl@ 00000ce0 records:1, size/record:12,table size:16

      .task34:copy 224 bytes from load addr=80000100 to run addr=00010000

      BINT@00000cf0 records:1,size/record:12,table size:16

      .task12:copy 256 bytes from load addr=80000000 to run addr=00010000

      拷貝表信息有3條記錄,第一條記錄說明拷貝表段task12_ctbl的存儲地址為 0x0cd0,有 1個記錄,每個記錄的大小為12字節(jié),拷貝表的大小為16字節(jié)。.task12段的加載地址為0x80000000,運行地址為0x00010000,拷貝的長度為256字節(jié)。加載.task12模塊時從0x8000000拷貝256個字節(jié)到0x00010000;同理,第二條記錄列出了拷貝表段task34_ctbl的具體信息;第三記錄是引導時加載的拷貝表信息,由于在鏈接命令文件中指定.task12段為引導時的加載段,所以第三條記錄與第一條相同。

      2)公共模塊程序設計

      公共模塊包含了硬件設備的初始化、中斷服務程序、公用函數(shù)和運行主函數(shù)。從圖2可以看出,主函數(shù)主要完成兩項任務,初始化和Overlay模塊的加載執(zhí)行。初始化工作主要包括芯片支持庫初始化,系統(tǒng)時鐘初始化。在初始化系統(tǒng)時鐘之前要求關閉所有中斷。對外部總線進行初始化才能使目標板上擴展的SDRAM存儲器正常工作。本實例使用定時器調度Overlay模塊的執(zhí)行,所以還需進行定時器初始化和中斷初始化。從圖2也可以看出,在定時器事件的驅動下,兩個Overlay模塊交替加載和執(zhí)行。當?shù)谝粋€定時器事件發(fā)生時,ovlyFlag=0,將.task34段拷貝到運行內存,然后依次執(zhí)行task3()、task4()和 IntSub()函數(shù)。 task3()和 task4()是聯(lián)合段.task34中的函數(shù),必須先將.task34段拷貝到內存中才能調用這兩個函數(shù)。IntSub()是公共模塊中的函數(shù),它常駐內存,隨時都可以執(zhí)行。當?shù)诙€定時器事件發(fā)生時,ovlyFlag=1,將.task12段拷貝到運行內存,然后依次執(zhí)行 task1()、task2()和IntAdd()函數(shù)。這三個函數(shù)是聯(lián)合段.task12中的函數(shù),必須先將.task12段拷貝到內存中才能調用。

      3)功能模塊設計

      本應用實例設計了4個功能模塊。模塊1設計了該模塊的局部函數(shù) int IntAdd(int,int)(實現(xiàn)兩個整數(shù)的加法)和功能函數(shù) int task1(int, int)(加載后由主函數(shù)調用)。 task1 調用局部函數(shù)IntAdd,并將所得到的結果與全局變量ratio相乘。模塊2設計了一個功能函數(shù)task2(int,int),加載后由主函數(shù)調用。task2調用全局函數(shù)IntSub(int,int),實現(xiàn)兩個整數(shù)的減法。模塊3和模塊4分別設計了一個功能函數(shù)task3(int,int)和 task4(int, int),task3 實現(xiàn)了兩個整數(shù)的乘積,task4 實現(xiàn)了兩個整數(shù)的平方和。

      2.2 Overlay模塊的動態(tài)加載

      多個Overlay模塊共享同一塊運行內存,因而必須根據(jù)需要動態(tài)地加載Overlay模塊。要實現(xiàn)這個目的,必須知道鏈接器所產生的拷貝表結構??截惐淼慕Y構信息定義在運行支持庫的頭文件cpy_tbl.h中。對于每個需要動態(tài)加載的模塊,鏈接器都會為其產生一個COPY_RECORD結構對象(包含裝載地址、運行地址和需要拷貝的代碼長度)。鏈接器將所有COPY_RECORD結構對象組織成一個COPY_TABLE結構對象。根據(jù)COPY_TABLE的內容,將代碼從裝載地址拷貝到運行地址[6]。裝載的task34模塊的程序代碼如程序2所示。

      圖2 main函數(shù)的執(zhí)行流程Fig.2 The execution process of main funtion

      程序2 Overlay段task34的裝載和執(zhí)行

      copy_in(&task34_ctbl); //拷貝.task34 段代碼

      CACHE_invAllL1p(); //更新 cache

      asm(“nop 5”); //消除流水線的影響

      val1=task3(taskIn1,taskIn1); //調用 task3,執(zhí)行 a*b

      val2=task4(taskIn1,taskIn1); //調 用 task4, 執(zhí) 行a*a+b*b

      val3=IntSub(val1,val2);//調用全局函數(shù),執(zhí)行 2a-3b

      值得注意的是,當所使用的DSP具有cache(高速緩存)時,在調用完copy_in函數(shù)之后,執(zhí)行剛剛加載的代碼之前,應該刷新程序cache的內容。

      3 Overlay程序的調試和運行

      多個Overlay模塊共享一塊運行內存,代碼是動態(tài)加載的,程序的跟蹤調試有所不同。

      3.1 加載Overlay代碼模塊到外部內存

      在實際的運行中,為了調試方便,暫時將Overlay模塊的加載地址定位在SDRAM,待調試完成后,再將其定位到目標系統(tǒng)的程序存儲器。調試時,在下載.task12段和.task34段時可能會出現(xiàn)錯誤提示,可以暫時忽略此錯誤。當下載完成后,在外總線初始化函數(shù)EMIFInit()之后設置斷點,然后運行程序到所設置的斷點處,此時外部總線已被初始化,重新下載*.out文件,就能避免這個錯誤。

      3.2 Overlay代碼的跟蹤調試

      在跟蹤調試時,如果想跟蹤調試某一Overlay模塊,可以暫時不把該模塊放在聯(lián)合段中,待調試完成后,再把它添加到聯(lián)合段中。為此,除了要修改鏈接命令文件外,還要修改Overlay模塊的加載代碼。例如要調試.task34模塊,可以修改鏈接器命令文件中部分代碼如下:

      SECTIONS

      ……

      /*.task34:{debug ask3.obj(.text), debug ask4.obj(.text) }

      load>>SDRAM, table(_task34_ctbl)*/

      ……

      }

      由于在聯(lián)合段中刪除了.task34段,鏈接器將把目標文件task3.obj和task4.obj的.text段鏈接到統(tǒng)一的.text輸出段中,并把它定位到ROM存儲器。經上述修改,函數(shù)task3(int,int)和task4(int,int)將成為公共代碼的一部分,編譯、鏈接、下載后,即可在源代碼級跟蹤調試它們。此方法是將要調試的模塊作為公共模塊的一部分,任何時候都可在源代碼級跟蹤調試。

      4 結束語

      文中通過討論DSP覆蓋(Overlay)程序設計技術的開發(fā)方法,有效解決了由于DSP的內部存儲器有限,當程序代碼及其使用的數(shù)據(jù)區(qū)大于DSP的內部存儲器時,則會限制DSP程序的開發(fā)這一困局,并在TMS320C6713B上通過調試和運行,成功應用于基于DSP的繼電保護測試儀中,取得了滿意的結果。

      [1]馬喜強,劉維亞,鄭喜鳳.基于多通信方式實現(xiàn)DSP程序在線編程[J].電子器件,2013,36(1):112-115.MA Xi-qiang,LIU Wei-ya,ZHENG Xi-feng.On-line programming of DSP based on multiple communications[J].Chinese Journal of Electron Devices,2013,36(1):112-115.

      [2]李聲飛,代華山.基于串口通信的DSP程序動態(tài)加載技術[J].電訊技術,2011(6):121-124.LI Sheng-fei,DAI Hua-shan.Dynamic locading technology for DSP program based on serial communication[J].Telecommunication Engineering,2011(6):121-124.

      [3]孫濱,周楊,郭曉東.動態(tài)鏈接庫技術及其應用[M].電腦編程技巧與維護,2009.SUN Bin,ZHOU Yang,GUO Xiao-dong.Dynamic link library technology and application[M].Computer Programming Skills and Maintenance,2009.

      [4]王楠.基于Overlay期刊的網(wǎng)絡開放學術資源建設與服務研究[D].蘭州:蘭州大學,2010.

      [5]夏爽.DSP的二級加載及Bootloader研究 [J].電腦編程技巧與維護,2009(10):8-11,16.XIA Shuang.The secondrey loading based on DSP and bootloader research[M].Computer Programming Skills and Maintenance,2009(10):8-11,16.

      [6]楊音穎.基于Overlay網(wǎng)絡的應用層組播系統(tǒng)的研究與實現(xiàn)[J].計算機應用,2005,24(9):61-64.YANG Yin-ying.Application level multicast system based on overlay network[J].Computer Applications,2005,24(9):61-64.

      猜你喜歡
      拷貝存儲器程序設計
      靜態(tài)隨機存儲器在軌自檢算法
      基于Visual Studio Code的C語言程序設計實踐教學探索
      計算機教育(2020年5期)2020-07-24 08:52:56
      從細節(jié)入手,談PLC程序設計技巧
      電子制作(2019年9期)2019-05-30 09:42:04
      唐氏綜合征是因為“拷貝”走樣了
      高職高專院校C語言程序設計教學改革探索
      PLC梯形圖程序設計技巧及應用
      存儲器——安格爾(墨西哥)▲
      基于Nand Flash的高速存儲器結構設計
      文件拷貝誰最“給力”
      一種存儲器容錯設計方法
      屯留县| 云浮市| 五原县| 钦州市| 庆元县| 皋兰县| 托里县| 陇南市| 建平县| 光泽县| 玉山县| 新郑市| 河源市| 广州市| 拉孜县| 观塘区| 平凉市| 浪卡子县| 宜兰县| 特克斯县| 礼泉县| 江津市| 普宁市| 咸宁市| 嘉定区| 辉南县| 石景山区| 个旧市| 武陟县| 长兴县| 怀柔区| 临澧县| 盘锦市| 格尔木市| 昭平县| 穆棱市| 绥阳县| 鄂伦春自治旗| 巴楚县| 嵊州市| 花垣县|