OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 33990|回复: 37

[分享]Keil编译后的Code,RO,RW,ZI分别表示什么以及和芯片Flash、SRAM的对应关系

  [复制链接]

10

主题

45

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
259
金钱
259
注册时间
2013-4-8
在线时间
1 小时
发表于 2015-7-17 13:16:26 | 显示全部楼层 |阅读模式
在使用keil开发STM32应用程序时,点击Build后在Build Output窗口中经常会有如下信息:



以前一直好奇这几个参数和实际使用的STM32芯片中Flash和SRAM的对应关系,于是上网搜了一圈,做如下总结:
  • 这些参数的单位是Byte
  • 图中几个参数分别代表
    • Code:代码的大小
    • RO:常量所占空间
    • RW:程序中已经初始化的变量所占空间
    • ZI:未初始化的static变量和全局变量以及堆栈所占的空间
  • 上述参数和芯片Flash以及SRAM的对应关系是
    • Flash占用大小=Code+RO+RW
    • SRAM占用大小=RW+ZI
不知道有没有人会像我一样好奇为什么RW参数同时参与了Flash和SRAM占用量的计算。这是因为Flash部分的属性是Read-Only的,而SRAM虽然是Read-Write但里面数据不能掉电保存,所以只能把已经初始化的值保存到ROM里,上电后再拷贝到SRAM中进行读写操作,即两部分都需要留出RW变量所占用的空间。这里给出的解释比较详细,在此我参照着用STM32F407ZGT6图解一下。
STM32F407ZGT6的Flash大小为1MB,SRAM大小为(128KB+64KB)。这里SRAM之所以分开表示是因为在芯片内部前面的128KB和后面的64KB地址不是连续的,后面的64KB在ST官方叫做CCM (core coupled memory) ,据说是由内核直接访问的,不能由外设访问(见原帖2楼)。下面给出的示意图中只标出了前面的128KB的SRAM空间。红色部分表示STM32F407ZGT6提供的Flash和SRAM大小。



结合上图说下STM32F407ZGT6的启动过程(采用Cortex-M4、Cortex-M3内核的芯片基本都是这个过程):上电后首先从 0x00000000(映射到0x08000000,这里只考虑从内部Flash启动)处获得中断向量表,然后在运行用户代码之前会在标号2处有一段引导代码负责把存在Flash中的初始化变量的值Copy到SRAM中对应的变量位置(标号3),之后把ZI区全部清零(标号4),之后才正式开始运行用户代码(标号5)。

对于详细的启动过程,这个帖子写得比较详细,可以试试~

参考资料:
http://stackoverflow.com/questions/5430284/rom-and-ram-in-arm
http://blog.csdn.net/he_ning/article/details/35226125
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/4027.html
http://www.amobbs.com/thread-5517029-1-1.html
http://anlx27.iteye.com/blog/1575848


每天奋斗一点点,终究会有成功的那一天
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
发表于 2015-7-17 14:03:37 | 显示全部楼层
言简意赅,说的很清楚,同时字体选择、图片搭配起来看着很舒服,谢谢分享,向你致敬!

有一点疑问:"之后把其他未初始化的SRAM变量全部清零(标号4)",CPU会进行清零这个操作吗,未初始化的SRAM变量不一定是0吧
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复 支持 反对

使用道具 举报

10

主题

45

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
259
金钱
259
注册时间
2013-4-8
在线时间
1 小时
 楼主| 发表于 2015-7-17 16:14:13 | 显示全部楼层
回复【2楼】龙之谷:
---------------------------------
ZI的意思是Zero Initialized,从字面的理解应该是用0进行初始化。我之前知道static类型的值不初始化的话会自动初始化为0,而局部变量的值不初始化则是未定义的。
不过刚刚搜了一些文档,在ARM官方的文档中心有这样一段说明"The ANSI C specification states that static data that is not initialized explicitly should be initialized to zero. The compiler therefore places both zero-initialized and uninitialized data in the same ZI section, which is zero-filled at run time by the C library initialization code."大意是ANSI C规范规定没有进行初始化的static型变量应该被初始化为0。编译器本身把需要初始化为0的变量(static型变量)和不需要初始化的变量统一放在了ZI区,并在C语言库的初始化代码中对ZI区的所有内容进行了初始化为0的操作。
文档地址:http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/4027.html
最后我用一个简单的串口打印程序进行了验证:
static int s_value;
int g_value;
int main(void)
{
    int l_value;
    printf("The static value is %d\n", s_value);
    printf("The global value is %d\n", g_value);
    printf("The local  value is %d\n", l_value);
}
最终输出的值都为0,所以ZI区域的内容应该是全部被初始化为0的(堆栈也在ZI区),定义在堆栈中的局部变量会随着堆栈的使用而呈现不同的值(但一开始也是0),因此局部变量不初始化使用是危险的。
每天奋斗一点点,终究会有成功的那一天
回复 支持 反对

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
发表于 2015-7-17 16:31:12 | 显示全部楼层
回复【3楼】k0becheng:
---------------------------------
有理有据,佩服你的探究能力,多谢赐教
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复 支持 反对

使用道具 举报

10

主题

45

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
259
金钱
259
注册时间
2013-4-8
在线时间
1 小时
 楼主| 发表于 2015-7-17 16:40:54 | 显示全部楼层
回复【4楼】龙之谷:
---------------------------------
^_^
每天奋斗一点点,终究会有成功的那一天
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-7-17 19:08:45 | 显示全部楼层
不错,cool
回复 支持 反对

使用道具 举报

11

主题

38

帖子

0

精华

初级会员

Rank: 2

积分
102
金钱
102
注册时间
2014-11-12
在线时间
0 小时
发表于 2015-7-18 21:02:58 | 显示全部楼层
markcool
回复 支持 反对

使用道具 举报

4

主题

14

帖子

0

精华

初级会员

Rank: 2

积分
54
金钱
54
注册时间
2015-7-25
在线时间
1 小时
发表于 2015-7-26 15:39:53 | 显示全部楼层
赞楼主,学习了
回复 支持 反对

使用道具 举报

9

主题

55

帖子

0

精华

初级会员

Rank: 2

积分
119
金钱
119
注册时间
2015-1-28
在线时间
44 小时
发表于 2015-8-18 21:41:30 | 显示全部楼层
楼主,请问0x08100000~0x20000000这块灰色区域是什么呢?是不存在的意思吗?可是手册上说只能CPU访问的那64KB内存定位于0x10000000呢,这是怎么回事呀?还有为什么这里是code呀,这不是还有64KB内存吗?新手,求指教。。。
回复 支持 反对

使用道具 举报

10

主题

45

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
259
金钱
259
注册时间
2013-4-8
在线时间
1 小时
 楼主| 发表于 2015-8-28 08:19:53 | 显示全部楼层
回复【9楼】琉璃:
---------------------------------
嗯,是表示物理上不存在的意思。你指的位于0x10000000的64KB的CCM(core coupled memory)RAM是存在的,但这里为了便于讨论作了简化(因为STM32有些系列是没有这块RAM的,比如F1xx系类;另外也是因为我自己也没用过CCM,不好作讨论)。这里是Code区是ARM公司给出的一个总体性的划分,至于为何ST官方在Code区放了一块RAM我也没细查过,感兴趣你可以自己研究下。
每天奋斗一点点,终究会有成功的那一天
回复 支持 反对

使用道具 举报

15

主题

786

帖子

5

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3223
金钱
3223
注册时间
2015-7-26
在线时间
811 小时
发表于 2015-9-14 09:50:53 | 显示全部楼层
谢谢分享!mark!
我的博客:http://blog.csdn.net/itdo_just
回复 支持 反对

使用道具 举报

22

主题

104

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
235
金钱
235
注册时间
2015-5-4
在线时间
34 小时
发表于 2015-11-2 15:09:20 | 显示全部楼层
图文并茂,讲的很详细,楼主真是很考究的人~
回复 支持 反对

使用道具 举报

4

主题

44

帖子

0

精华

初级会员

Rank: 2

积分
185
金钱
185
注册时间
2013-8-11
在线时间
25 小时
发表于 2015-11-20 21:20:55 | 显示全部楼层
谢谢分享!mark!
回复 支持 反对

使用道具 举报

2

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
94
金钱
94
注册时间
2015-11-20
在线时间
22 小时
发表于 2015-11-28 20:37:24 | 显示全部楼层
楼主牛人, 佩服
回复 支持 反对

使用道具 举报

1

主题

5

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2015-11-25
在线时间
6 小时
发表于 2015-12-4 21:44:59 | 显示全部楼层
领教了,秒赞楼主
回复 支持 反对

使用道具 举报

1

主题

3

帖子

0

精华

新手入门

积分
27
金钱
27
注册时间
2015-12-2
在线时间
0 小时
发表于 2015-12-5 15:34:17 | 显示全部楼层
大牛啊,学习了!
回复 支持 反对

使用道具 举报

0

主题

4

帖子

0

精华

新手上路

积分
36
金钱
36
注册时间
2014-7-16
在线时间
4 小时
发表于 2016-1-2 18:57:18 | 显示全部楼层
谢谢讲解。。。
回复 支持 反对

使用道具 举报

2

主题

20

帖子

0

精华

高级会员

Rank: 4

积分
604
金钱
604
注册时间
2016-1-2
在线时间
81 小时
发表于 2016-1-2 20:48:44 | 显示全部楼层
真是惭愧,我从来不管这些的
学习 了
回复 支持 反对

使用道具 举报

23

主题

73

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
449
金钱
449
注册时间
2016-7-12
在线时间
121 小时
发表于 2016-8-6 09:47:42 | 显示全部楼层
图片上是编译后的结果,我的SRAM只有192K,但是编译结果里RW+ZI明显大于192K了,程序能正常运行,这是为什么?
QQ截图20160806094511.png
回复 支持 反对

使用道具 举报

32

主题

883

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4036
金钱
4036
注册时间
2015-11-14
在线时间
545 小时
发表于 2016-8-6 09:56:01 | 显示全部楼层
有外部SRAM?
回复 支持 反对

使用道具 举报

23

主题

73

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
449
金钱
449
注册时间
2016-7-12
在线时间
121 小时
发表于 2016-8-8 08:16:56 | 显示全部楼层

没有使用外部SRAM啊?
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手上路

积分
27
金钱
27
注册时间
2015-7-21
在线时间
1 小时
发表于 2016-8-23 08:42:27 | 显示全部楼层
莫问1990 发表于 2016-8-6 09:47
图片上是编译后的结果,我的SRAM只有192K,但是编译结果里RW+ZI明显大于192K了,程序能正常运行,这是为什 ...

大量占用RAM其实都是数组,而不是变量。
数组是在运行过程中才会用到,而且不一定用满,例如串口或者一些记录几百个列表的buffer。
当运行过程中我们没有那么多内容要用到那么多buffer(例如最大是100个情况的存储,实际只用到60个,那么40个的内存是没有用到的),而c编译是不检测内存边界的,这也是c指针经常引发问题的原因,只有在运行时读写了不存在或不能访问的ram时,才会引发异常。
所以,RAM超出了限定值,但可以运行,不代表能够稳定长期运行。
还有就是一般都是自定义的数组太多,这个应该写程序时就预算到了呀,应该用更大的ram的芯片。
还有一点就是可能是编译器设定的堆栈过大了,这些堆栈是给动态分配内存指针用的,如果程序没有申请动态内存和释放的操作,那么这块是不会用到也是浪费了的。做好内存规划能够在资源不是极大富裕时降低芯片成本。
回复 支持 反对

使用道具 举报

1

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
115
金钱
115
注册时间
2016-7-19
在线时间
12 小时
发表于 2016-8-23 12:00:40 | 显示全部楼层
感谢分享,受教了,
回复 支持 反对

使用道具 举报

1

主题

140

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
290
金钱
290
注册时间
2016-8-15
在线时间
20 小时
发表于 2016-8-23 12:18:19 | 显示全部楼层
涨姿势
回复 支持 反对

使用道具 举报

4

主题

14

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
310
金钱
310
注册时间
2016-8-24
在线时间
15 小时
发表于 2016-8-24 01:05:44 | 显示全部楼层
堆栈概念不怎么懂,看起来好吃力!!!
回复 支持 反对

使用道具 举报

119

主题

439

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1185
金钱
1185
注册时间
2015-9-18
在线时间
422 小时
发表于 2016-8-24 15:00:24 | 显示全部楼层
感谢大神指导~
电子爱好者
回复 支持 反对

使用道具 举报

2

主题

194

帖子

0

精华

高级会员

Rank: 4

积分
981
金钱
981
注册时间
2015-9-20
在线时间
148 小时
发表于 2016-8-24 15:07:09 | 显示全部楼层
顶一个
回复 支持 反对

使用道具 举报

3

主题

9

帖子

0

精华

初级会员

Rank: 2

积分
54
金钱
54
注册时间
2015-12-17
在线时间
9 小时
发表于 2016-8-24 15:41:53 | 显示全部楼层
mark...
回复 支持 反对

使用道具 举报

119

主题

439

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1185
金钱
1185
注册时间
2015-9-18
在线时间
422 小时
发表于 2016-8-24 15:42:00 | 显示全部楼层
小弟按照大神推荐的帖子,想了解下stm32的启动过程,遇到一点问题,恳请指教
我使用的是探索者STM32F407ZGT6开发板,MDK5开发环境
废话不多说,先上图
00000.jpg
我使用默认的Flash启动方式

1>按照帖子上说,在进入硬件DEBUG模式后,

0x08000000(0x00000000是它的别名区,值相同)存放的是SP,没错,结果完全正确

0x08000004(0x00000004是它的别名区,值相同)存放的是PC,问题来了,0x08000004(0x00000004)的值是0x080007F5,而PC的值是0x08000288(这里使用相同的大小端模式),为什么???


2>我想知道,这个默认的映射别名区的大小是多大,在哪里设置的?

电子爱好者
回复 支持 反对

使用道具 举报

1

主题

4

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2016-6-17
在线时间
5 小时
发表于 2016-9-12 14:47:02 | 显示全部楼层
学习了,thks
回复 支持 反对

使用道具 举报

11

主题

179

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1103
金钱
1103
注册时间
2016-7-19
在线时间
168 小时
发表于 2016-12-9 10:27:02 | 显示全部楼层
讲解很详细,谢谢分享!
回复 支持 反对

使用道具 举报

11

主题

179

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1103
金钱
1103
注册时间
2016-7-19
在线时间
168 小时
发表于 2016-12-9 10:27:20 | 显示全部楼层
讲解很详细,谢谢分享!
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

初级会员

Rank: 2

积分
51
金钱
51
注册时间
2016-12-13
在线时间
20 小时
发表于 2016-12-21 10:59:00 | 显示全部楼层
讲的不错,学习了!
回复 支持 反对

使用道具 举报

2

主题

15

帖子

0

精华

新手上路

积分
49
金钱
49
注册时间
2016-4-30
在线时间
13 小时
发表于 2016-12-21 21:00:14 | 显示全部楼层
之前在做bootloader时就遇到这个问题,之前的疑问是APP程序生成的bin文件都是text段或conststring等,那bss段和data段数据是怎么转移到新的IAP程序中呐,猜想rom段还应该会有data段数据,同时留意到APP程序生成的hex文件中只有rom中的地址,并且在rom的最后面还有一段数据,楼主这里证明了这些
回复 支持 反对

使用道具 举报

8

主题

145

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
462
金钱
462
注册时间
2016-12-14
在线时间
75 小时
发表于 2017-3-11 08:22:03 | 显示全部楼层
mark..
回复 支持 反对

使用道具 举报

9

主题

209

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1358
金钱
1358
注册时间
2015-12-19
在线时间
108 小时
发表于 2017-3-11 08:28:51 来自手机 | 显示全部楼层
顶。顶。顶。
回复 支持 反对

使用道具 举报

3

主题

37

帖子

0

精华

初级会员

Rank: 2

积分
118
金钱
118
注册时间
2017-3-11
在线时间
15 小时
发表于 2017-3-11 16:49:22 | 显示全部楼层
见教了!
回复 支持 反对

使用道具 举报

0

主题

0

帖子

0

精华

新手入门

积分
1
金钱
1
注册时间
2021-1-6
在线时间
0 小时
发表于 2017-3-30 20:41:40 | 显示全部楼层
学习了,mark
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-18 12:33

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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