hehelloook 发表于 2012-11-29 13:18:02

求助关于MSP430F5438内存RAM问题


现在在做个小东西,用到SD卡和SPI存储设备,后来程序一下载完就不知道跑到哪里去了,通过调试查到原因为定义的RAM变量过大,但是编译时根据提示所用的DATA memory 远小于MSP430F5438的16KB RAM。

实在没有办法了,只能回头从最小的程序来偿试RAM的问题,平台为IAR EW430-EV 5.10.1,TI的USB仿真器,主芯片为MSP430F5438,以下为点灯测试程序。
///
#include <msp430x54x.h>
///
#define CPU_F ((dou××e)16000000)
#define DelayNms(x) __delay_cycles((long)(CPU_F*(dou××e)x/1000.0))
///
#define Max 4678
unsigned char TestGroup ={0};
///
void main(void)
{
unsigned long i;
WDTCTL = WDTPW + WDTHOLD;
///
P5SEL |= 0x0C ; // 端口功能选择振荡器
UCSCTL6 &= ~XT2OFF ; // 振荡器使能
UCSCTL3 |= SELREF_2 ; // FLLref = REFO
UCSCTL4 |= SELA_2 ; // ACLK=REFO,SMCLK=DCO,MCLK=DCO
do
{
UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG); // 清除 XT2,XT1,DCO 错误标志
SFRIFG1 &= ~OFIFG ;
}while(SFRIFG1&OFIFG) ; // 检测振荡器错误标志
UCSCTL6 |= XT2DRIVE0 + XT2DRIVE1 ; // XT2 驱动模式 24~32MHz
UCSCTL4 |= SELS_5 + SELM_5 ; // SMCLK = MCLK = XT2
///
P6DIR |= BIT1;
while(1)
{
for(i =0;i <Max;i++)
{
TestGroup =i;
}
P6OUT ^= BIT1;
DelayNms(300);
}
//__bis_SR_register(GIE);
}
///

说明:此程序很简单,点灯用,软件设置使用默认方式,优化程度也是默认的Low级别,编译好后下载到目标板,程序中定义了一个大数组
(1)当数组个数Max个数小于或等于4677时,程序能下载也能运行点灯,当Max个数为4677时,编译提示为:182 bytes of CODE memory ,4837 bytes of DATA memory (+ 18 absolute ) ,此时程序能正常运行;
(2)当数组个数Max个数大于4677时,程序一下载完毕就跑飞,当Max个数为4678时,编译提示为:182 bytes of CODE memory ,4838 bytes of DATA memory (+ 18 absolute ) ,此时程序就不能正常运行了;
(3)MSP430F5438的手册里说明为16KB RAM,这个是大B,也就是字节的意思。按我的理解,那么程序编译完以后占用的4838 bytes of DATA memory 远远低于16KB,为什么程序还跑飞了呢?各位能不能回答一下?谢谢

orzorzorzorz 发表于 2012-11-29 23:05:01

本帖最后由 orzorzorzorz 于 2012-11-29 23:08 编辑

原因在于上电时,狗默认是打开的,你的4678个字节的全局数据是在进main函数之前进行初始化,初始化4677个时,没超过狗的时间,4678个就超过狗的时间了。
解决方法:在low_level_init函数关闭狗,问题就解决了!
或者,全局数据后面不要赋值 ={0},等进了main函数,关闭狗后自己显式的初始化0也可以
祝你好运。
最好了解下cpu在进入main函数之前都要做些什么工作,比如全局变量有初始值的数据如何初始化的,没初始值的数据就不需要初始化了,这些工作都是在main函数之前干的。

geniuskim 发表于 2012-11-29 23:16:17

ls正解
这点iar居然一点提示都没有
很多人都被骗过

hehelloook 发表于 2012-11-30 11:08:58

本帖最后由 hehelloook 于 2012-11-30 12:08 编辑

orzorzorzorz 发表于 2012-11-29 23:05 static/image/common/back.gif
原因在于上电时,狗默认是打开的,你的4678个字节的全局数据是在进main函数之前进行初始化,初始化4677个时 ...

感谢你的回复,按照你的两种办法,我都偿试了一下,但是还是没有解决:
(1)在主函数的一开始,调用low_level_init()关狗;
(2)那个长数组没有初始化,而只定义为unsigned char TestGroup;

以前在网上买过一个5438的开发板,但是买回来生由于种种原因没有进行学习,那个开发板里面有一个例程:RTOS+GUI,编译以后内存占用为13 382 bytes of DATAmemory (+ 130 absolute ) ,但是可以正常运行,我查了查也找不出窍门在哪,然后没办法请教了卖板子的人。哎,很遗憾,没有得到答案。。。

orzorzorzorz 发表于 2012-11-30 12:42:26

hehelloook 发表于 2012-11-30 11:08 static/image/common/back.gif
感谢你的回复,按照你的两种办法,我都偿试了一下,但是还是没有解决:
(1)在主函数的一开始,调用low_ ...

针对你的(1),你的操作有问题啊,low_level_init怎么可能被main函数调用呢,他是运行在主函数之前的!

hehelloook 发表于 2012-11-30 13:40:34

orzorzorzorz 发表于 2012-11-30 12:42 static/image/common/back.gif
针对你的(1),你的操作有问题啊,low_level_init怎么可能被main函数调用呢,他是运行在主函数之前的! ...

本人才粗学浅,你能说得仔细点吗,如何在main前运行那个函数?谢谢

orzorzorzorz 发表于 2012-11-30 14:23:29

hehelloook 发表于 2012-11-30 13:40 static/image/common/back.gif
本人才粗学浅,你能说得仔细点吗,如何在main前运行那个函数?谢谢

C:\Program Files\IAR Systems\Embedded Workbench 6.0\430\src\lib
low_level_init.c

/**************************************************
*
* This is a template for early application low-level initialization.
*
* Copyright 1996-2010 IAR Systems AB.
*
* $Revision: 5993 $
*
**************************************************/

/*
* The function __low_level_init it called by the start-up code before
* "main" is called, and before data segment initialization is
* performed.
*
* This is a template file, modify to perform any initialization that
* should take place early.
*
* The return value of this function controls if data segment
* initialization should take place. If 0 is returned, it is bypassed.
*
* For the MSP430 microcontroller family, please consider disabling
* the watchdog timer here, as it could time-out during the data
* segment initialization.
*/

/*
* To disable the watchdog timer, include a suitable device header
* file (or "msp430.h") and add the following line to the function
* below:
*
*   WDTCTL = WDTPW+WDTHOLD;
*
*/


#include <intrinsics.h>

int __low_level_init(void)
{
/* Insert your low-level initializations here */

/*
   * Return value:
   *
   *1 - Perform data segment initialization.
   *0 - Skip data segment initialization.
   */

return 1;
}

hehelloook 发表于 2012-11-30 18:31:44

orzorzorzorz 发表于 2012-11-30 14:23 static/image/common/back.gif
C:\Program Files\IAR Systems\Embedded Workbench 6.0\430\src\lib
low_level_init.c



依照大侠的高见,改为下面函数,加了头文件:#include <msp430.h>,问题还是没有解决,我用的是一楼的那个简单程序。

int __low_level_init(void)
{
/* Insert your low-level initializations here */
   WDTCTL = WDTPW+WDTHOLD;
/*
   * Return value:
   *
   *1 - Perform data segment initialization.
   *0 - Skip data segment initialization.
   */

return 1;
}

另外,我似乎觉得不是这个看门狗的原因,因为我手里有买的开发板一个例程:RTOS+GUI,编译以后内存占用为13 382 bytes of DATAmemory (+ 130 absolute ) 。有RTOS+GUI这个例程序中,关狗没用用到__low_level_init而是一般的关法,定义的数组大得多,同样的硬件,同样的电脑,同样的平台,就是能正常运行。郁闷,继续求助~!

活力的小冰 发表于 2014-2-11 09:09:59

请问现在问题解决了吗?
页: [1]
查看完整版本: 求助关于MSP430F5438内存RAM问题