搜索
bottom↓
回复: 1

Keil编程环境下STM32内存管理

[复制链接]

出0入0汤圆

发表于 2011-12-17 08:13:26 | 显示全部楼层 |阅读模式
 Keil编程环境下STM32内存管理研究

  非常简单的一个工程,没有用到任何IO操作,与STM32有关的仅仅只有芯片的选择,即其SRAM大小有区别。除了自己编写的代码外,仅仅增加了2个文件,即system_stm32f10x.c和startup_stm32f10x_hd.s,其中为了对startup_stm32f10x_hd.s进行修改,将其从库文件夹复制到了项目文件夹中。


  代码1

  int main()

  {

  int a,b,c,d;

  a=10;b=20;

  c=a+b;

  for(;;);

  }

  myex1.c(3): warning: #550-D: variable "c" was set but never used

  linking...

  Program Size: Code=796 RO-data=336 RW-data=20 ZI-data=1636

  FromELF: creating hex file...

  "myex1.axf" - 0 Error(s), 1 Warning(s).

  代码2

  int main()

  { const int x=16;

  int a,b,c,d;

  a=10;b=20;

  c=a+b;

  for(;;);

  }

  myex1.c(2): warning: #177-D: variable "x" was declared but never referenced

  myex1.c(3): warning: #550-D: variable "c" was set but never used

  linking...

  Program Size: Code=800 RO-data=336 RW-data=20 ZI-data=1636

  FromELF: creating hex file...

  "myex1.axf" - 0 Error(s), 2 Warning(s).

  说明:

  (1)Code增加了4字节

  (2)其余没有任何变化

  代码3

  int main()

  { const int x=16;

  int myArry[100];

  int i;

  int a,b,c,d;

  a=10;b=20;

  c=a+b;

  for(i=0;i<100;i++)

  myArry=i;

  for(;;);

  }

  myex1.c(2): warning: #177-D: variable "x" was declared but never referenced

  myex1.c(3): warning: #550-D: variable "myArry" was set but never used

  myex1.c(5): warning: #550-D: variable "c" was set but never used

  myex1.c(5): warning: #177-D: variable "d" was declared but never referenced

  linking...

  Program Size: Code=816 RO-data=336 RW-data=20 ZI-data=1636

  FromELF: creating hex file...

  "myex1.axf" - 0 Error(s), 4 Warning(s).

  分析:程序中增加了数组myArry,Code增加为816字节,但是RO-data等仍未变化

  代码4

  int main()

  { const int x=16;

  int myArry[100]={1,2,3,4,5,6};

  int i;

  int a,b,c,d;

  a=10;b=20;

  c=a+b;

  for(i=0;i<100;i++)

  myArry=i;

  for(;;);

  }

  myex1.c(2): warning: #177-D: variable "x" was declared but never referenced

  myex1.c(3): warning: #550-D: variable "myArry" was set but never used

  myex1.c(5): warning: #550-D: variable "c" was set but never used


myex1.c(5): warning: #177-D: variable "d" was declared but never referenced

  linking...

  Program Size: Code=1024 RO-data=360 RW-data=20 ZI-data=1636

  FromELF: creating hex file...

  "myex1.axf" - 0 Error(s), 4 Warning(s).

  分析:

  (1)由于myArry作了初始化,因此RO-data增加了 360-336=24字节。原因是32位机中int型变量是32位的,占4字节,所以初始6个值后,增加了24字节。

  (2)再增加初始化变量的数量,则RO-data随之增加,而Code不再变化,也就是Code由代码3的816字节增加到1024字节,是增加了初始化处理的代码量。

  根据以上分析,似乎与已知资料有冲突。

  ***************************************************

  RO是程序中的指令和常量

  RW是程序中的已初始化变量

  ZI是程序中的未初始化的变量

  由以上3点说明可以理解为:

  RO就是readonly,

  RW就是read/write,

  ZI就是zero

  ****************************************************

  如果按此说明,增加变量应该增加RO,但从代码1到代码2的变化来看,仅是增加了Code,却没有增加RO。

  初始化变量时,应该增加RW,但是从代码2~代码4,RW却没有任何变化。

  看来这个说法只能适用于ARM芯片,即运行时需要将代码调入RAM运行的芯片,对于STM32这类芯片并不完全适用。

  以下再作研究:

  当使用 int myArray[300]时:



  当使得int myArray[100]时:



  应该是向下生成的??

  而且与芯片无关,无论选择6K RAM还是48K RAM都是如此,且当数组再大时,就会将地址置于小于0x2000000的地址,但编译并不报错。

  当使得int myArray[450]时:



  当然,执行是错误的。

  当int myArray[409]时:正指向0x2000000

  去掉其他变量,对于这个地址没有影响!

  代码5

  int myArray[400]={1,2,3,4,5,6,7,8,9,10,11,12,13,14};

  int main()

  { const int x=16;

  int a,b,c,d;

  int i;

  a=10;b=20;

  c=a+b;

  for(i=0;i<100;i++)

  myArray=i;

  for(i=0;i<100;i++)

  c+=myArray;

  d+=x;

  for(;;);

  }

  编译结果:

  compiling myex1.c...

  linking...

  Program Size: Code=876 RO-data=336 RW-data=1620 ZI-data=1636

  FromELF: creating hex file...

  "myex1.axf" - 0 Error(s), 0 Warning(s).

  分析:

  本段程序将数组作为全局变量来定义,情况立即发生了变化。RW-data变成了1620。其中的1600应该是这个数组增加的4*400=1600,而20则是代码1~代码4中一直都有的。

  经查验资料,局部变量是放在栈中的,如果栈定义得较小,那么变量数就很少。因此当数组在main内部定义时,是作为局部变量从栈中分配内存给它。所以在代码1~代码4的实验中还发现,即便更改芯片,从6KB RAM的C4到48KB RAM的VC,编译的结果不发生变化,其原因就在于不论哪种芯片,给它分配的栈是固定的。栈的大小应该在启动代码中修改。





  更改这个:startup_stm32f10x_hd.s可以更改栈的大小。

  改成500后的编译结果如下:

  linking...

  Program Size: Code=1048 RO-data=392 RW-data=20 ZI-data=1892

  FromELF: creating hex file...

  "myex1.axf" - 0 Error(s), 0 Warning(s).

  说明:注意到ZI-ddata已发生了变化。

  至此可以明白RO-data ZI-data应该是针对栈来说的。即栈中的只读数据和零数据??但是RW-data似乎又有所不同,这里还应该再次探究。

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2012-11-24 12:25:31 | 显示全部楼层
谢谢楼主的研究。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-6-15 07:03

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表