DSP2812 RAM不够用的解决方法【转载】

    科技2022-08-07  107

    DSP2812的FLASH虽然很大,但是程序在这个FLASH区域运行的速度与在RAM中运行速度相比要慢很多,为此通常的做法是将需要快速运行的程序copy到ram中运行,通常将中断子程序以及中断中调用的其他子程序copy到RAM中运行,对于一些不需要太快速度处理的程序可以不管,让其在FLASH中运行。

    将FLASH中程序copy到RAM中的运行的RAM需要连续地址区域,而最大的连续区域仅8k,对于一些大软件来说就不够用了;扩充可用RAM区间分两个阶段,通常例程中cmd文件中的分配并未将单个8k都用起来,所以第一个阶段是将可用最大的8k RAM连起来作为一个连续区间,如下:

    RAML0 : origin = 0x008000, length = 0x002000 /* on-chip RAM block L0 */

    同时将与其相邻的另外段RAML01屏蔽,如下:

    // RAML1 : origin = 0x00A000, length = 0x000000 /* on-chip RAM block L1 */

    通过以上修改可以将RAML0调整到最大的8k,这样对应着可copy子程序的ramfuncs就是8k:

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

    第二阶段,是将RAMH0的8k也作为可拷贝程序的区间,有一些采用了将.test拆分的方法(http://blog.sina.com.cn/s/blog_c82fc4020102wdms.html),个人觉得太麻烦,实际上可以再定义一个ramfuncs2,采用和 ramfuncs同样的定义方式,将RUN = RAML0改为RUN = RAMH0岂不是更简单?

    ramfuncs :  LOAD = FLASHD,       RUN = RAML0,       LOAD_START(_RamfuncsLoadStart),       LOAD_END(_RamfuncsLoadEnd),       RUN_START(_RamfuncsRunStart),       PAGE = 0 ramfuncs2 : LOAD = FLASHB, /* 与RAMH0同属PAGE1区 */       RUN = RAMH0,       LOAD_START(_RamfuncsLoadStart2),       LOAD_END(_RamfuncsLoadEnd2),       RUN_START(_RamfuncsRunStart2),       PAGE = 1

    改成上面的代码后会首先报错,找不到RamfuncsLoadStart2、_RamfuncsLoadEnd2和_RamfuncsRunStart2,仍采用复制

    的方法,首先找到_RamfuncsLoadStart定义的位置(DSP281x_GlobalPrototypes.h),改后如下:

    extern Uint16 RamfuncsLoadStart;     extern Uint16 RamfuncsLoadEnd;     extern Uint16 RamfuncsRunStart;

    //以下为新增加     extern Uint16 RamfuncsLoadStart2;     extern Uint16 RamfuncsLoadEnd2;     extern Uint16 RamfuncsRunStart2;

    定义好之后,就是在主程序中将程序从FLASH中copy到RAM的部分再复制一次,如:

    InitSysCtrl();

    MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);//将定义在ramfuncs段中的数据从FLASH拷贝到RAM中

    MemCopy(&RamfuncsLoadStart2, &RamfuncsLoadEnd2, &RamfuncsRunStart2);//将定义在ramfuncs2段中的数据从FLASH 拷贝到RAM中(新增加)

    InitFlash();

    经过以上更改后,就可以将子程序放到ramfuncs2中了,如下:

    #pragma CODE_SECTION(delay, “ramfuncs”);     #pragma CODE_SECTION(delay3, “ramfuncs”);     #pragma CODE_SECTION(SQRT_FPGA, “ramfuncs”);

    #pragma CODE_SECTION(CTR_PRAM_CAL, “ramfuncs2”); //ramfuncs2为新增加数据段     #pragma CODE_SECTION(CTR_PRAM_CAL3, “ramfuncs2”);     #pragma CODE_SECTION(CTR_PRAM_CAL4, “ramfuncs2”);

    经过以上的两个步骤,可以充分利用DSP2812中总共18k RAM中的16k,剩下的2k可用于存储全局变量或者局部变量,完整的 cmd文件如下(可直接复制替换):

    MEMORY { PAGE 0: /* Program Memory / / Memory (RAM/FLASH/OTP) blocks can be moved to PAGE1 for data allocation */

    ZONE0 : origin = 0x002000, length = 0x002000 /* XINTF zone 0 / ZONE1 : origin = 0x004000, length = 0x002000 / XINTF zone 1 / RAML0 : origin = 0x008000, length = 0x002000 / on-chip RAM block L0 / //0x001000 ZONE2 : origin = 0x080000, length = 0x080000 / XINTF zone 2 / ZONE6 : origin = 0x100000, length = 0x080000 / XINTF zone 6 / OTP : origin = 0x3D7800, length = 0x000800 / on-chip OTP / FLASHJ : origin = 0x3D8000, length = 0x002000 / on-chip FLASH / FLASHI : origin = 0x3DA000, length = 0x002000 / on-chip FLASH / FLASHH : origin = 0x3DC000, length = 0x004000 / on-chip FLASH / FLASHG : origin = 0x3E0000, length = 0x004000 / on-chip FLASH / FLASHF : origin = 0x3E4000, length = 0x004000 / on-chip FLASH / FLASHE : origin = 0x3E8000, length = 0x004000 / on-chip FLASH / FLASHD : origin = 0x3EC000, length = 0x004000 / on-chip FLASH / FLASHC : origin = 0x3F0000, length = 0x004000 / on-chip FLASH / FLASHA : origin = 0x3F6000, length = 0x001F80 / on-chip FLASH / CSM_RSVD : origin = 0x3F7F80, length = 0x000076 / Part of FLASHA. Program with all 0x0000 when CSM is in use. / BEGIN : origin = 0x3F7FF6, length = 0x000002 / Part of FLASHA. Used for “boot to Flash” bootloader mode. / CSM_PWL : origin = 0x3F7FF8, length = 0x000008 / Part of FLASHA. CSM password locations in FLASHA */

    /* ZONE7 : origin = 0x3FC000, length = 0x003FC0 /* XINTF zone 7 available if MP/MCn=1 / ROM : origin = 0x3FF000, length = 0x000FC0 / Boot ROM available if MP/MCn=0 / RESET : origin = 0x3FFFC0, length = 0x000002 / part of boot ROM (MP/MCn=0) or XINTF zone 7 (MP/MCn=1) / VECTORS : origin = 0x3FFFC2, length = 0x00003E / part of boot ROM (MP/MCn=0) or XINTF zone 7 (MP/MCn=1) */

    PAGE 1 : /* Data Memory / / Memory (RAM/FLASH/OTP) blocks can be moved to PAGE0 for program allocation / / Registers remain on PAGE1 */

    RAMM0 : origin = 0x000000, length = 0x000400 /* on-chip RAM block M0 / RAMM1 : origin = 0x000400, length = 0x000400 / on-chip RAM block M1 / // RAML1 : origin = 0x00A000, length = 0x000000 / on-chip RAM block L1 / FLASHB : origin = 0x3F4000, length = 0x002000 / on-chip FLASH / RAMH0 : origin = 0x3F8000, length = 0x002000 / on-chip RAM block H0 */ }

    /* Allocate sections to memory blocks. Note: codestart user defined section in DSP28_CodeStartBranch.asm used to redirect code execution when booting to flash ramfuncs user defined section to store functions that will be copied from Flash into RAM */

    SECTIONS {

    /* Allocate program areas: */ .cinit : > FLASHC PAGE = 0//FLASHA .pinit : > FLASHC, PAGE = 0//FLASHA .text : > FLASHC PAGE = 0//FLASHA codestart : > BEGIN PAGE = 0 ramfuncs : LOAD = FLASHD, RUN = RAML0, LOAD_START(_RamfuncsLoadStart), LOAD_END(_RamfuncsLoadEnd), RUN_START(_RamfuncsRunStart), PAGE = 0 ramfuncs2 : LOAD = FLASHB, RUN = RAMH0, LOAD_START(_RamfuncsLoadStart2), LOAD_END(_RamfuncsLoadEnd2), RUN_START(_RamfuncsRunStart2), PAGE = 1

    csmpasswds : > CSM_PWL PAGE = 0 csm_rsvd : > CSM_RSVD PAGE = 0

    /* Allocate uninitalized data sections: */ .stack : > RAMM0 PAGE = 1 .ebss : > RAMM1 PAGE = 1 .esysmem : > RAMM1 PAGE = 1

    /* Initalized sections go in Flash / / For SDFlash to program these, they must be allocated to page 0 */ .econst : > FLASHC PAGE = 0 //FLASHA .switch : > FLASHC PAGE = 0 //FLASHA

    /* Allocate IQ math areas: / IQmath : > FLASHA PAGE = 0 //FLASHC / Math Code / IQmathTables : > ROM PAGE = 0, TYPE = NOLOAD / Math Tables In ROM */

    /* .reset is a standard section used by the compiler. It contains the / / the address of the start of _c_int00 for C Code. /* /* When using the boot ROM this section and the CPU vector / / table is not needed. Thus the default type is set here to / / DSECT */ .reset : > RESET, PAGE = 0, TYPE = DSECT vectors : > VECTORS PAGE = 0, TYPE = DSECT

    }

    经过以上改动后,新扩展的RAM区实测可用! 一些理解:LOAD_START(_RamfuncsLoadStart)表示告诉编译器将这一段编译之后产生的起始地址存入RamfuncsLoadStart变量中,其他的变量也类似,这样在主程序运行时的MemCopy()才会找到相应的数值,也就是说LOAD_START(_RamfuncsLoadStart)这句是赋值功能。

    文章转载自:https://www.cnblogs.com/liwei-chengdu/p/9407358.html

    Processed: 0.008, SQL: 8