代码段(.text段)太长,导致无法在线仿真的解决办法 ——拆分.text段

代码段(.text段)太长,导致无法在线仿真的解决办法

——拆分.text

 

DSP2812的代码被编译器放在.text段中,当代码越长时,.text段就越大。而一个段只能放在一块连续的RAM空间中2812较大的RAM空间有2块,一块是L0L1,长度8kw(8K×16),另一块是H0,长度也是8kw(8K×16)如果代码非常长,以至于.text段大到超过8kw(8K×16),超过了任何一块连续RAM的大小,则无法在RAM中运行,也就无法在线仿真这个程序了。对调试是非常不方便的。

最近有个同事编写了一个2000多行的程序,所有代码都放在了一个文件中,.text段长度为0x20a0,超过了8k,只好采取屏蔽掉一部分代码,调试剩下的那部分的方法。但这样还是不够方便除了硬件上扩展片外RAM外,还有两个解决的办法一个是用#pragma CODE_SECTION把一些函数定位到text以外的段,来达到削减text段长度的目的另外一个方法就是拆分.text段。而拆分又分为两种方式:手动拆分和自动拆分,两种拆分均可通过配置.cmd文件来实现

.text段由许多.obj组成,每个.obj来自一个c源文件。拆分.text段只能以.obj为最小单位,也就是说.obj是不能再拆分的.text段中最大的一个objMain_nonBIOS.obj(与主函数所在文件同名),是主函数所在的文件Main_nonBIOS.c编译而来。把它单独放在一个段.text1里,余下的.obj放在另一个段.text2中。然后把.text1段和.text2段分别定位到H0L0L1中。这就是拆分的基本思路

当然了,如果Main_nonBIOS.obj的大小超过了8kw,这样还是解决不了问题,这时就需要把Main_nonBIOS.c中的一部分代码转移到别的c文件中,为主函数所在的c文件瘦身。推荐的做法是主函数所在的文件中只有主函数,别的函数都按照功能分别放在不同的c文件中,这样就不会出现某个.obj特别大的情况了

 

第一种拆分方法:手动拆分.text

修改后的.cmd文件如下:请注意加深字体颜色部分。

MEMORY
{
PAGE 0:   /* Program Memory */
   RAML0L1         : origin = 0x008000, length = 0x002000     

  OTP             : origin = 0x3D7800, length = 0x000400     
   FLASH_ABCDEFGHIJ : origin = 0x3D8000, length =0x01FF80     
   CSM_RSVD         : origin= 0x3F7F80, length = 0x000076     
   BEGIN_FLASH      : origin = 0x3F7FF6,length = 0x000002     
   PASSWORDS        : origin =0x3F7FF8, length = 0x000008     
   BEGIN_H0        : origin = 0x3F8000, length = 0x000002    

 /*Jumpto H0Boot Mode中,完成Boot后调到H0 SARAM的入口处(0x3F8000~1)继续执行,用户需要在0x3F8000~1处编写转移程序调用_c_int00函数完成C运行环境的初始化(其实就是DSP281x_CodeStartBranch.asm中定义的codestart段),BEGIN_H0 is used for the"boot to H0" bootloader mode(booting up in Jump to H0 mode)*/
   H0SARAM         : origin = 0x3F8002, length = 0x001FFE     

   IQTABLES         : origin= 0x3FF000, length = 0x000B50     
   BOOTROM          :origin = 0x3FFB50, length = 0x000470     
   RESET           : origin = 0x3FFFC0, length = 0x000002     
   VECTORS          :origin = 0x3FFFC2, length = 0x00003E  

PAGE 1 :   /*Data Memory */
   RAMM0M1          :origin = 0x000000, length = 0x000800
    
}


SECTIONS
{
/*** Compiler RequiredSections ***/

/* Program memory (PAGE0) sections */
   .text1     : {Main_nonBIOS.obj(.text)}>H0SARAM, PAGE = 0 /*主函数Main_nonBIOS.c所在的.obj单独放在一个段,配置到H0*/

.text2     : {*(.text)}> RAML0L1, PAGE = 0 /*剩余的.obj放在另一个段,配置到L0L1*/

                                    
   .cinit    : > RAML0L1,        PAGE = 0
   .const     : >RAML0L1,        PAGE = 0
   .econst   : > RAML0L1,        PAGE = 0      

   .pinit     : >RAML0L1,        PAGE = 0
   .reset    : > RESET,          PAGE = 0,TYPE = DSECT 
   .switch    : >RAML0L1,        PAGE = 0

/* Data Memory (PAGE 1)sections */
  .bss             : > RAMM0M1,        PAGE = 1
   .ebss            : > RAMM0M1,        PAGE = 1
   .cio             : > RAMM0M1,        PAGE = 1
   .stack           : > RAMM0M1,        PAGE = 1
  .sysmem           : >RAMM0M1,        PAGE = 1
   .esysmem          :> RAMM0M1,        PAGE = 1

/*** User DefinedSections ***/
   codestart         : >BEGIN_H0,       PAGE = 0   

/*DSP281x_CodeStartBranch.asm中定义的codestart段分配到0x3F8000~1处,使得Jump to H0Boot Mode的最后能跳到codestart段处代码,调用_c_int00函数完成C运行环境的初始化   */         
   internalMemFuncs: > H0SARAM,        PAGE =0               
   secureRamFuncs    : >RAML0L1,        PAGE = 0                
}

/******************* end of file ************************/


第二种拆分方法:自动拆分.text

实际上.text段是可以被自动拆分的。使用>>符号就可以达到这个目的。基本思想和第一种方法一样,只是如何具体拆分交给编译器去完成。这种方法的.cmd文件如下:


MEMORY
{
PAGE 0:    /* Program Memory */
   RAML0L1          :origin = 0x008000, length = 0x002000     

  OTP             : origin = 0x3D7800, length = 0x000400    
   FLASH_ABCDEFGHIJ : origin = 0x3D8000, length =0x01FF80     
   CSM_RSVD         : origin= 0x3F7F80, length = 0x000076     
   BEGIN_FLASH      : origin = 0x3F7FF6,length = 0x000002     
   PASSWORDS        : origin =0x3F7FF8, length = 0x000008     
   BEGIN_H0         : origin= 0x3F8000, length = 0x000002     
   H0SARAM          :origin = 0x3F8002, length = 0x001FFE     
   IQTABLES         : origin= 0x3FF000, length = 0x000B50     
   BOOTROM          :origin = 0x3FFB50, length = 0x000470     
  RESET            : origin= 0x3FFFC0, length = 0x000002     
   VECTORS          :origin = 0x3FFFC2, length = 0x00003E   

PAGE 1 :   /* Data Memory */
   RAMM0M1          :origin = 0x000000, length = 0x000800   

}


SECTIONS
{
/*** Compiler Required Sections ***/

/* Program memory (PAGE 0) sections */
.text           : {*(.text)} >> H0SARAM | RAML0L1,   PAGE = 0 /*.text段将在H0SARAMRAML0L1中自动拆分*/
   
  .cinit            : >RAML0L1,        PAGE = 0
  .const            : >RAML0L1,        PAGE = 0
  .econst           : >RAML0L1,        PAGE =0      
  .pinit            : >RAML0L1,        PAGE = 0
  .reset            : >RESET,          PAGE = 0, TYPE =DSECT 
  .switch           : >RAML0L1,        PAGE = 0

/* Data Memory (PAGE 1) sections */
  .bss             : > RAMM0M1,        PAGE = 1
  .ebss             :> RAMM0M1,        PAGE = 1
  .cio             : > RAMM0M1,        PAGE = 1
  .stack            : >RAMM0M1,        PAGE = 1
  .sysmem           : >RAMM0M1,        PAGE = 1
   .esysmem          :> RAMM0M1,        PAGE = 1

/*** User Defined Sections ***/
   codestart         : >BEGIN_H0,       PAGE =0                

   internalMemFuncs : >H0SARAM,        PAGE =0               
   secureRamFuncs    : >RAML0L1,        PAGE =0                 
}

/******************* end of file ************************/


最后要说的是,如果.text的总大小超过了片上RAM的总和,就无法通过拆分解决问题了,这时要想把代码全部RAM中运行(使用F2812_EzDSP_RAM_lnk.cmd),进行在线仿真,就只有硬件扩展RAM一种方法了。否则,只能把代码在Flash中运行了(使用F2812.cmd)。

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值