DSP

F2812程序从Flash搬到RAM中运行

2019-07-13 17:17发布

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:                
          PRAML0      : origin = 0x008000, length = 0x000800               FLASHA      : origin = 0x3F6000, length = 0x001F80     } 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地址上运行。