f2812把程序從FLASH搬到RAM中運行 【轉】


例程: 

第一步:


// Functions that will be run from RAM need to be assigned to

// a different section.  This section will then be mapped using

// the linker cmd file.

#pragma CODE_SECTION(EPwm1_timer_isr, "ramfuncs");

#pragma CODE_SECTION(EPwm2_timer_isr, "ramfuncs");


MAIN()

{

// These are defined by the linker (see F2808.cmd)在CMD里面定義的變量

extern Uint16 RamfuncsLoadStart;

extern Uint16 RamfuncsLoadEnd;

extern Uint16 RamfuncsRunStart;


User specific code, enable interrupts:


// Copy time critical code and Flash setup code to RAM

// This includes the following ISR functions: EPwm1_timer_isr(), EPwm2_timer_isr()

// EPwm3_timer_isr and and InitFlash();

// The  RamfuncsLoadStart, RamfuncsLoadEnd, and RamfuncsRunStart

// symbols are created by the linker. Refer to the F2808.cmd file.

   MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);


// Call Flash Initialization to setup flash waitstates

// This function must reside in RAM

   InitFlash();//FLASH初始化的函數不能在FLASH里面運行,必須拷到別的內存空間里運行才能對FLASH進行初始化。

}


第二步:將要從FLASH里面加載到RAM的函數定義到"ramfuncs"

// Functions that will be run from RAM need to be assigned to

// a different section.  This section will then be mapped to a load and

// run address using the linker cmd file.


#pragma CODE_SECTION(InitFlash, "ramfuncs");


第三步:

CMD文件:

MEMORY

{

    PAGE 0:    /* Program Memory */

           /* Memory (RAM/FLASH/OTP) blocks can be moved to PAGE1 for data allocation */


          PRAML0      : origin = 0x008000, length = 0x000800     /* on-chip RAM block L0 */

          FLASHA      : origin = 0x3F6000, length = 0x001F80     /* on-chip FLASH */

}

SECTIONS

{

    ramfuncs            : LOAD = FLASHA,

                         RUN = PRAML0,

                         LOAD_START(_RamfuncsLoadStart),

                         LOAD_END(_RamfuncsLoadEnd),

                         RUN_START(_RamfuncsRunStart),

                         PAGE = 0

}



總結:在MAP文件里:從FLASH加載到RAM運行的程序會有二個實際的存儲空間,一個在FLASH里面,另一個在RAM里。

ramfuncs           : LOAD = FLASHA,//指定了要加載程序存儲在FLASH里面的地址段。

                     RUN = PRAML0,//指令了在RAM里運行程序的RAM空間段。

                     LOAD_START(_RamfuncsLoadStart),//_RamfuncsLoadStart指向了FLASH里的程序起始地址, 

                     LOAD_END(_RamfuncsLoadEnd),//_RamfuncsLoadEnd指向了FLASH里的程序結束地址


 ramfuncs功能指令了存在於FLASHA里面的一個連續代碼段空間,並且為這段代碼空間分配了一個在RAM里運行的指針(RamfuncsRunStart),應用時我們道先要將加載到RAM里運行的程序通過#pragma CODE_SECTION指令分配到這一個連續的代碼空間,然后通過MEMCPY指令存在於FLASH里的代碼復制到能足夠容納的RAM空間里


MAP文件里的表現:

SECTION ALLOCATION MAP

ramfuncs   0    003f65d6    0000004d     RUN ADDR = 00008000

                  003f65d6    0000001b     DSP2802x_SysCtrl.obj (ramfuncs)

                  003f65f1    00000004     DSP2802x_usDelay.obj (ramfuncs)

                  003f65f5    0000002e     Example_2802xFlash.obj (ramfuncs)


.cinit     0    003f6623    00000019     

                  003f6623    0000000e     rts2800_ml.lib : exit.obj (.cinit)

                  003f6631    0000000a                    : _lock.obj (.cinit)

                  003f663b    00000001     --HOLE-- [fill = 0]



GLOBAL SYMBOLS: SORTED ALPHABETICALLY BY Name 

003f6623   _RamfuncsLoadEnd

003f65d6   _RamfuncsLoadStart

00008000   _RamfuncsRunStart


GLOBAL SYMBOLS: SORTED BY Symbol Address 

00008000   _RamfuncsRunStart

0000801b   _DSP28x_usDelay//三個從FLASH里加載RAM里運行的程序

0000801f   _EPwm1_timer_isr

00008035   _EPwm2_timer_isr


003f65d6   _RamfuncsLoadStart

003f6623   cinit

003f6623   ___cinit__

003f6623   _RamfuncsLoadEnd//在FLASH的地址空間上面並沒有具體的函數表現




程序運行上的表現:只要程序一運行到上面的三個函數,CCS程序PC指針就會指向相應RAM地址上運行。



=================================================================================

=================================================================================

如何將flash中的程序搬到ram中執行 (http://blog.sina.com.cn/s/blog_afdc25690101cuzt.html)


4.F28335如何燒寫代碼到flash中並運行?

首先使用添加C:\ti\controlSUITE\device_support\f2833x\v133\DSP2833x_common\cmd\F28335.cmd。此文件即為配置代碼到flash中的TI官方配置文件。

然后參考C:\ti\controlSUITE\device_support\f2833x\v133\DSP2833x_examples_ccsv4\flash_f28335。添加以下代碼:MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);將一些在內存中運行的代碼從flash復制到內存中,然后程序才能正常運行。

5.寫好的代碼再ram中能正常運行但是燒寫到flash中后,函數DSP28x_usDelay()不能正常運行為什么?

因為在DSP2833x_usDelay.asm中有.sect "ramfuncs",即把該函數定義在段"ramfuncs"中, 而此段需要在內存中運行,故需要使用函數

MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);將ramfuncs段復制到內存中然后運行。只算以這樣設計是因為函數DSP28x_usDelay()精准運行對運行速度有要求故必須放在段"ramfuncs"中。參考:http://blog.sina.com.cn/s/blog_9388c4140100vs0r.html

6.cmd中以下代碼如何解釋?

   ramfuncs   : LOAD = FLASHD, 
                         RUN = RAML0, 
                         LOAD_START(_RamfuncsLoadStart),
                         LOAD_END(_RamfuncsLoadEnd),
                         RUN_START(_RamfuncsRunStart),
                         PAGE = 0

第1行表示該段的裝載在PAGA0的FLASHD中
第2行表示該段的運行地址在PAGE0的RAML0中
LOAD_START(_RamfuncsLoadStart)令編譯器創建了一個變量RamfuncsLoadStart,該變量指向段ramfuncs的裝載地址的首地址(LOAD_START為編譯偽指令,請見CCS的幫助文檔);
LOAD_END(_RamfuncsLoadEnd)令編譯器創建了一個變量RamfuncsLoadEnd,該變量指向段ramfuncs的裝載地址的末地址(LOAD_END為編譯偽指令,請見CCS的幫助文檔);
RUN_START(_RamfuncsRunStart)令編譯器創建了一個變量RamfuncsRunStart,該變量指向段ramfuncs的運行地址的首地址(LOAD_START為編譯偽指令,請見CCS的幫助文檔);
從第1和2行可以看出,段ramfuncs中的函數DSP28x_usDelay()的裝載地址和運行地址是不同的,本程序中裝載在Flash的塊FLASHD中,而在SARAM L0中運行,這只是目標,實際運行時DSP並不會自動將Flash中的代碼拷貝到SARAM中,因此需要手動添加代碼來完成。
在C函數中,為了使用變量RamfuncsLoadStart、RamfuncsLoadEnd和RamfuncsRunStart,必須先聲明,本工程在文件DSP2833x_GlobalPrototypes.h中做了如下聲明:
extern Uint16 RamfuncsLoadStart;
extern Uint16 RamfuncsLoadEnd;
extern Uint16 RamfuncsRunStart;
然后就可以使用了。在Main.c中,使用MemCopy()函數將段ramfuncs中的函數DSP28x_usDelay()的代碼從裝載地址RamfuncsLoadStart—RamfuncsLoadEnd拷貝到RamfuncsRunStart開始的SARAM空間中。之后在程序運行時,只要調用DSP28x_usDelay()函數,都會自動地指向SARAM中相應的函數入口地址,這一點是自動完成的。MemCopy()函數原型在MemCopy.c中,DSP2833x_GlobalPrototypes.h聲明。

7.如何將一個函數放到ram中運行?

參考TI公司頭文件中自帶InitFlash函數,這些函數會以CODE_SECTION申明。如:#pragma CODE_SECTION(InitFlash, "ramfuncs");



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM