DSP28335使用时的经验总结 主要是使用大维度的二维数组的一些问题

该部分主要是想使用较大维度的数组,我这里是112X112的。

1.数组or指针

首先是数组的使用,可以用指针,也可以直接数组,其实在内存当中的二维数组就是一维的,它是先存一行,再存其他行,在连续地址当中的存储顺序就是:a[0][0]、a[0][1]、a[0][2]....a[1][0]、a[1][1]、a[1][2].............'关于指针跟上面等效表示数组就是:(*((Uint16 *)a+(N*i)+j)),其中N是数组的列数大小,即一行有多少个数据,然后i是行号,j是列。关于直接使用数组和指针的区别其实是程序运行速度,一般来讲指针会运行的更快一些,但也要取决于代码怎么写,因为他们的实质都是内存地址,所以如果是小白开始学,只是想实现功能,直接使用数组就好。

2.当数组作为参数传给函数时

因为数组和指针是共用的,所以定义了a[][]之后,使用**a也是可以的,甚至使用&,也是可以调用定义的数组,只是各自含义不同,所以当函数的输入参数有数组或者指针时要注意。这里可以给个实例,在函数里面

float *factor(float **e,Uint16 n) 
{
    Uint16 i = 0;
	Uint16 j = 0;
    float factor0[3];
    for(i=0;i<n;i++)
	{
		for(j=0;j<n;j++)
		{

            *((float *)e+(n*i)+j) = n*i+j;
        }
    }
    factor0[0]  = *((float *)e);  //[0][0]
	factor0[1]  = *((float *)e+1);;  //[0][1]
	factor0[2]  = *((float *)e+n);   //[1][0]
    return factor0;
}

然后在main里面调用时:

float e[N][N];
float * factor0;

factor0 = factor((float **)e,N) 

一定要注意当数组时函数输入或者输出时,调用的方式,大家可以自行对比,如果理解比较困难,就照着写就行,或者在CCSdebug窗口当中观测这些变量的值,总之如果使用不当,进行数据传输时,可能传的就是一些地址。

3.关于在CCS当中使用大数组时

我这里是V6版本,首先是不能进行纯软件仿真的,所以需要根据以前的版本进行软件配置,才能进行纯软件仿真,最后其实是配置不同的仿真器参数,进行纯软件仿真或者连开发板进行硬件仿真,这个大家可以百度一下CCS配置软件仿真就可以完成。然后是关于内存大小的问题,我起初是将二维数组的N设置成define,把算法功能完成之后,当N较小的时候,是可以进行计算的,但是当N调大之后,程序就不能成功运行,甚至会卡在main函数最开始的几步变量声明和系统时钟初始化里面,一直循环,不会进行下面的算法计算,但是不会报任何的错。

起初以为是内存分配的问题,在view里面是可以看到内存使用的情况的,我已经分配了一个较大内存,甚至是xintf里面的zone7外扩地址,但还是不行。经过几天的实验,总结如下:

当进行大规模的数组运算时:

要使用全局变量或者动态分配,其中全局变量就是定义在main上面的变量,测试是可以实现大规模数组的,动态分配没有测试成功,应该是我不会分配。其中为什么全局变量可以,局部变量不可以,好像是因为,局部变量是在当前一个固定的部分进行定义的,这个大小好像是固定且较小的,所以当数组本身就大时,就没有连续的其余地址来放置,而全局变量是放在cmd文件当中的,可以自定义大小。

而这个cmd文件,其实归根结底是对28335的内存地址的声明和分配,就是在page0和page1当中对地址段进行命名以及起始地址和长度,这个是根据28335的实际内存地址进行分配,要注意的就是对xintf的地址进行使用时,应该是要先配置或者初始化的,我之前就是直接将.bss分配到zone7的地址当中,那么在debug时,就会在该部分的变量后面显示,该地址不可读。还有就是cmd文件是可以自己修改的,因为是初学,以为是配置文件。将芯片内存地址分好段之后(是可以将某些地址段拼起来的,只要地址不重复就行),就要对程序当中的代码段,变量等分配内存,就像是.text,.ebss,这些大家百度一下就知道。下面是我修改的一些cmd:

MEMORY
{
PAGE 0 :
   /* BEGIN is used for the "boot to SARAM" bootloader mode      */
   /* BOOT_RSVD is used by the boot ROM for stack.               */
   /* This section is only reserved to keep the BOOT ROM from    */
   /* corrupting this area during the debug process              */
   
   BEGIN      : origin = 0x000000, length = 0x000002     /* Boot to M0 will go here                      */
   BOOT_RSVD  : origin = 0x000002, length = 0x00004E     /* Part of M0, BOOT rom will use this for stack */               
 //  RAMM0      : origin = 0x000050, length = 0x0003B0
   RAMM0      : origin = 0x000050, length = 0x0007B0
//   RAML0      : origin = 0x008000, length = 0x001000
//   RAML1      : origin = 0x009000, length = 0x001000
 //  RAML2      : origin = 0x00A000, length = 0x001000
//   RAML3      : origin = 0x00B000, length = 0x001000
   ZONE6A     : origin = 0x100000, length = 0x00FC00    /* XINTF zone 6 - program space */ 
   CSM_RSVD   : origin = 0x33FF80, length = 0x000076     /* Part of FLASHA.  Program with all 0x0000 when CSM is in use. */
   CSM_PWL    : origin = 0x33FFF8, length = 0x000008     /* Part of FLASHA.  CSM password locations in FLASHA            */
   ADC_CAL    : origin = 0x380080, length = 0x000009  //0x000009
   RESET      : origin = 0x3FFFC0, length = 0x000002
   IQTABLES   : origin = 0x3FE000, length = 0x000b50
   IQTABLES2  : origin = 0x3FEB50, length = 0x00008c
   FPUTABLES  : origin = 0x3FEBDC, length = 0x0006A0
   BOOTROM    : origin = 0x3FF27C, length = 0x000D44               

         
PAGE 1 : 
//   RAMM1      : origin = 0x000400, length = 0x000400  //0x000400   /* on-chip RAM block M1 */
 //  RAML4      : origin = 0x00C000, length = 0x001000
  // RAML5      : origin = 0x00D000, length = 0x001000
//   RAML6      : origin = 0x00E000, length = 0x001000
 //  RAML7      : origin = 0x00F000, length = 0x001000
  RAML4      : origin = 0x008000, length = 0x008000
   ZONE7B     : origin = 0x20FC00, length = 0x000400 //0x000400    /* XINTF zone 7 - data space */

	SARAML0      : origin = 0x3F8000, length = 0x002000
}
 
 
SECTIONS
{
   /* Setup for "boot to SARAM" mode: 
      The codestart section (found in DSP28_CodeStartBranch.asm)
      re-directs execution to the start of user code.  */
   codestart        : > BEGIN,     PAGE = 0
   ramfuncs         : > RAMM0,     PAGE = 0    //RAML0
   .text            : > RAML4,     PAGE = 1   //RAML1
   .cinit           : > RAMM0,     PAGE = 0  //RAML0
   .pinit           : > RAMM0,     PAGE = 0   //RAML0
   .switch          : > RAMM0,     PAGE = 0   //RAML0
   
  .stack           : > RAMM0,     PAGE = 0    //RAMM1
   .ebss            : > RAML4,     PAGE = 1   //RAML4
   .econst          : > RAML4,     PAGE = 1        //RAML5
   .esysmem         : > RAMM0,     PAGE =0   //RAMM1

.bss            : > RAML4,     PAGE = 1

   IQmath           : > RAMM0,     PAGE = 0   //RAML1
   IQmathTables     : > IQTABLES,  PAGE = 0, TYPE = NOLOAD 
   IQmathTables2    : > IQTABLES2, PAGE = 0, TYPE = NOLOAD 
   FPUmathTables    : > FPUTABLES, PAGE = 0, TYPE = NOLOAD 
      
   DMARAML4         : > RAML4,     PAGE = 1
//   DMARAML5         : > RAML5,     PAGE = 1
 //  DMARAML6         : > RAML6,     PAGE = 1
//   DMARAML7         : > RAML7,     PAGE = 1
   
   ZONE7DATA        : > ZONE7B,    PAGE = 1

   .reset           : > RESET,     PAGE = 0, TYPE = DSECT /* not used                    */
   csm_rsvd         : > CSM_RSVD   PAGE = 0, TYPE = DSECT /* not used for SARAM examples */
   csmpasswds       : > CSM_PWL    PAGE = 0, TYPE = DSECT /* not used for SARAM examples */
   
   /* Allocate ADC_cal function (pre-programmed by factory into TI reserved memory) */
   .adc_cal     : load = ADC_CAL,   PAGE = 0, TYPE = NOLOAD
     
}

然后说一下测试过程:当我使用局部变量数组进行小维度计算时,是没有任何问题的,当把维度扩大,不会扩大,只是程序一直在初始化循环。然后将数组定义成全局变量,cmd文件就会报错,因为存放全局变量的.ebss地址是不够用的,(就是当程序只有内存问题时,是会自动报错的,因为之前一直在想是不是动态内存不够,因为算了一些这些变量的内存是够的,但是程序运行不成功,以为是计算过程中还有其他消耗内存,但现在看来就不是,在程序编译的时候,就已经自动考虑了内存的问题),所以拼接一块大的地址段给ebss即可。(有些也说可以在地址那里加上|,就是“或”别的地址,但好像还是不行,后面我就直接屏蔽掉一些,直接拼接成大段的地址空间)

猜你喜欢

转载自blog.csdn.net/qq_43811597/article/details/129816525