资源描述:
《在Keil环境编程中发现STM32内存管理存在的问题.doc》由会员上传分享,免费在线阅读,更多相关内容在学术论文-天天文库。
1、在Keil环境编程中发现STM32内存管理存在的问题 非常简单的一个工程,没有用到任何IO操作,与STM32有关的仅仅只有芯片的选择,即其SRAM大小有区别。图1是工程示意图,从图中可以看出,除了自己编写的代码外,仅仅增加了2个文件,即system_stm32f10x.c和startup_stm32f10x_hd.s,其中为了对startup_stm32f10x_hd.s进行修改,将其从库文件夹复制到了项目文件夹中。 图1 代码1 intmain() { inta,b,c,d; a=
2、10;b=20; c=a+b; for(;;); } myex1.c(3):warning:#550-D:variable“c”wassetbutneverused linking... ProgramSize:Code=796RO-data=336RW-data=20ZI-data=1636 FromELF:creatinghexfile... ”myex1.axf”-0Error(s),1Warning(s). 代码2 intmain() {constintx=16; in
3、ta,b,c,d; a=10;b=20; c=a+b; for(;;); } myex1.c(2):warning:#177-D:variable“x”wasdeclaredbutneverreferenced myex1.c(3):warning:#550-D:variable“c”wassetbutneverused linking... ProgramSize:Code=800RO-data=336RW-data=20ZI-data=1636 FromELF:creatingh
4、exfile... ”myex1.axf”-0Error(s),2Warning(s). 说明: (1)Code增加了4字节 (2)其余没有任何变化 代码3 intmain() {constintx=16; intmyArry[100]; inti; inta,b,c,d; a=10;b=20; c=a+b; for(i=0;iARM芯片,即运行时需要将代码调入RAM运行的芯片,对于STM32这类芯片并不完全适用。 以下再作研究: 当使用intmyArray[300]时:
5、 图2 当使得intmyArray[100]时: 图3 应该是向下生成的?? 而且与芯片无关,无论选择6KRAM还是48KRAM都是如此,且当数组再大时,就会将地址置于小于0x2000000的地址,但编译并不报错。 当使得intmyArray[450]时: 图4 当然,执行是错误的。 当intmyArray[409]时:正指向0x2000000 去掉其他变量,对于这个地址没有影响! 代码5 intmyArray[400]={1,2,3,4,5,6,7,8,9,10,
6、11,12,13,14}; intmain() {constintx=16; inta,b,c,d; inti; a=10;b=20; c=a+b; for(i=0;ipilingmyex1.c... linking... ProgramSize:Code=876RO-data=336RW-data=1620ZI-data=1636 FromELF:creatinghexfile... ”myex1.axf”-0Error(s),0Warning(s). 分析: 本段程序将数
7、组作为全局变量来定义,情况立即发生了变化。RW-data变成了1620。其中的1600应该是这个数组增加的4*400=1600,而20则是代码1~代码4中一直都有的。 经查验资料,局部变量是放在栈中的,如果栈定义得较小,那么变量数就很少。因此当数组在main内部定义时,是作为局部变量从栈中分配内存给它。所以在代码1~代码4的实验中还发现,即便更改芯片,从6KBRAM的C4到48KBRAM的VC,编译的结果不发生变化,其原因就在于不论哪种芯片,给它分配的栈是固定的。栈的大小应该在启动代码中修改。
8、 图5 更改这个:startup_stm32f10x_hd.s可以更改栈的大小。 改成500后的编译结果如下: linking... ProgramSize:Code=1048RO-data=392RW-data=20ZI-data=1892 FromELF:creatinghexfile... ”myex1.axf”-0Error(s),0Warning(s). 说明:注意到ZI-ddata已发生了变化。 至此可以明白RO-dataZI