|
在IAR中,堆和栈是分开设置的,堆用于存放全局变量,而栈用于存放局部变量。在最近的项目的中我就遇到了堆和栈溢出的情况。以下问题都是在NEC的0537中出现的。
一. 堆的溢出
在项目中,我定义了很多全局变量,而且这些全局变量都很大。刚开始定义的全局变量都没有问题,但是后来我定义了一个数组unsigned char testaddb[20];链接的时候出现了以下错误:
Error[e16]: Segment CSTACK (size: 0x80 align: 0x1) is too long for segment definition. At least 0x14 more bytes needed. The problem occurred while processing the segment
placement command "-Z(DATA)CSTACK+_CSTACK_SIZE=FB00-FE1F", where at the moment of placement the available memory ranges were "CODE:fda3-fe1f"
Reserved ranges relevant to this placement:
fb00-fda2 NEAR_Z
fda3-fe1f CSTACK
700-75f SADDR_A
780-79f SADDR_A
800-84f NEAR_A
860-867 NEAR_A
870-88f NEAR_A
898-8af NEAR_A
8b8-8bf NEAR_A
8f0-8f7 NEAR_A
900-907 NEAR_A
940-94f NEAR_A
978-987 NEAR_A
9b0-9c7 NEAR_A
a78-a7f NEAR_A
bc8-bcf NEAR_A
bf8-c17 NEAR_A
c80-c9f NEAR_A
cb0-cff NEAR_A
e00-e3f NEAR_A
e80-e87 NEAR_A
ea0-ea7 NEAR_A
ed8-edf NEAR_A
Error while running Linker
上面的错误意思是CSTACK (栈)设置得太大了,倒置变量没有地方放,需要0x14个字节,然后我在设置中将Stack的大小从0x80改成了0x6C(参考图一),再编译链接,错误消失。
(原文件名:clip_image002.jpg)
图一
二. 栈的溢出
不久堆的问题解决了,但是栈的问题又出现了。我编写了一个子函数,函数里定义了一个局部数组tempbuff[188];当程序这个函数的时候就出现了如下错误:
Thu Oct 07 16:20:36 2010: The stack 'Stack' is filled to 100% (128 bytes used out of 128). The warning threshold is set to 90.%
错误的意思就是'Stack'溢出了。
分析发现,我子函数中的局部变量需要188字节的空间,而实际栈中只有128字节,当然后爆错了。将数组改小或者将数组定义成全局变量就能解决问题。
三. 扩展RAM的使用
NEC0537有6144字节的扩展RAM,该区域空间除了不能作为堆栈存储器使用,其他功能和RAM区一样,所以我们可以把全局变量放到扩展RAM中,定义方法如下:
#pragma dataseg=IXRAM //--------------------将全局变量放在扩展RAM区间
__no_init unsigned char tempbuff[188];
#pragma dataseg=default
注1, 定义变量时__no_init不能去掉。
注2, 前面说道的堆栈存储器是0537中文资料上提到的,由于前面已将堆和栈分开提及,所以此处的堆栈存储器我认为是栈存储器。
以上为本人的个人观点,如有什么错误请大家拍砖。 |
|