zoukankan      html  css  js  c++  java
  • 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: icontrolSUITEdevice_supportf2833xv133DSP2833x_commoncmdF28335.cmd。此文件即为配置代码到flash中的TI官方配置文件。

    然后参考C: icontrolSUITEdevice_supportf2833xv133DSP2833x_examples_ccsv4flash_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");


  • 相关阅读:
    CVE-2017-17558漏洞学习
    USB键盘驱动分析
    CVE-2018-18955漏洞学习
    angr学习
    LeetCode递归解题模板
    USBD_STATUS
    Linux中/etc/passwd文件与/etc/shadow文件解析.
    USB设备架构
    HID Boot device.
    HID class request.
  • 原文地址:https://www.cnblogs.com/iable/p/4206834.html
Copyright © 2011-2022 走看看